PankovAlxndr
@PankovAlxndr
Fullstack web developer

Как работают дедлоки?

Можете простыми словами про блокировки пояснить?

Я записываю кучу данных батчами.
Бывает так, что записывается одно и то же в уникальный ключ, для этого есть on conflict do nothimg.
И я часто получаю дедлоки.

Как понял, потому что 2+ транзакции пытаюсь записать одно и то же значение уникального ключа, случается дедлок и проходит какая-то одна транзакция, чаще самая последняя, но мне так не подходит, у меня батч на 2000 строк, он отменяется весь при дедлоке.

Везде рекомендуют отсортировать записи и вставлять их в идентичном порядке в каждой из транзакций.

Но почему сортировка сработает, я не понимаю... (ps я не проверял пока что).
Типа Т1 вставляет "1" и Т2 вставляет в это же время "1".
Ну и что... и почему тут нет блокировки, чем это отличается от
Т1 вставлет "1"
Т2 вставляет "2"
Т1 вставлет "2"
Т2 вставляет "1"
не понимаю, можно на "котиках" объяснить?

Взял отсюда https://ru.stackoverflow.com/questions/1163202/dea...
  • Вопрос задан
  • 133 просмотра
Решения вопроса 1
AshBlade
@AshBlade
Просто хочу быть счастливым
Этот дедлок - проявление MVCC, механизма, чтобы несколько пользователей могли работать с БД одновременно.
Визуализировать эту ситуацию можно как перекрестные стрелки в зависимостях
667ef3df77793070431787.png

Если мы говорим про postgres, то если ты обновил какую-то запись (кортеж), то неявно получаешь на нее (запись) блокировку. Когда кто-то другой хочет обновить эту же запись, то ждет ее освобождения.
В данном случае (визуализация), 1 процесс выполнял UPDATE X, Y а другой UPDATE Y, X, т.е. первый взял блокировку сначала на X потом на Y, а другой - сначала на Y потом на X. Первая блокировка успешна, но вторые нет - они уже заняты.
В данном случае, разрешить их нельзя, т.к. оба ждут пока один из них снимет блокировку, но этого не произойдет. Блокировка со строки снимется по окончании транзакции.

Совет про сортировку взят, чтобы привнести единообразие в работу. Грубо говоря, дедлок появляется, когда нет согласованности в работе. Если оба выполнят UPDATE X, Y (в таком порядке), то дедлока не будет т.к. один из них сможет взять все блокировки на строки успешно. Поведение второго будет уже зависеть от уровня сериализации:
- Read committed - обновит новые данные
- Другие (repeatable read, serializable) - ошибка выполнения
Это уже детали MVCC в postgres (read uncommitted нет)
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы