Тупик при простом обновлении: ShareLock и AccessExclusiveLock - PullRequest
0 голосов
/ 08 июня 2018

Я заметил случайные тупики в журналах ошибок, причина в параллельном обновлении той же строки:

[1111]:LOG:  process 1111 detected deadlock while waiting for ShareLock on transaction 123456789 after 1000.095 ms
[1111]:DETAIL:  Process holding the lock: 2222. Wait queue: .
[1111]:CONTEXT:  while locking tuple (9999999,99) in relation "ccc"
[1111]:STATEMENT:  update ccc set modification_date_time=$1, ... where id=$7
[1111]:ERROR:  deadlock detected
[1111]:DETAIL:  Process 1111 waits for ShareLock on transaction 123456789; blocked by process 2222.
    Process 2222 waits for AccessExclusiveLock on tuple (9999999,99) of relation 55555 of database 66666; blocked by process 1111.
    Process 1111: update ccc set modification_date_time=$1, ... where id=$7
    Process 2222: update ccc set modification_date_time=$1, ... where id=$7
[1111]:HINT:  See server log for query details.

В приложении происходит следующее:

  1. Спящий режим загрузкисущность (строка)
  2. поле изменяется
  3. Hibernate сохраняет сущность в базе данных, в результате чего UPDATE оператор

Непонятно, почемуэто происходит, потому что это просто нормальное обновление, и процессы не должны зависеть друг от друга.Я понимаю, что это условие гонки, но с точки зрения приложения это не важно.

Я не до конца понимаю, что такое ShareLock и AccessExclusiveLock, поэтому у меня пока есть две идеи:

  • При изменении объекта Hibernate / DB должен повысить уровень блокировки, и это не удается, поскольку другой поток уже имеет некоторую блокировку в этой строке.Решение - заблокировать рано?
  • Иногда транзакции просто слишком медленные (> 1 с), и тупик дает ложное срабатывание.Решение - увеличить время ожидания?

1 Ответ

0 голосов
/ 08 июня 2018

Для возникновения взаимоблокировки должно быть задействовано более одного заблокированного объекта.

Проверьте, какие другие строки были обновлены транзакциями.Возможно, вы можете включить ведение журнала SQL, если можете себе это позволить.

Часто можно избежать взаимных блокировок, блокируя строки в каком-то определенном порядке, например, по возрастанию идентификатора.

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

Если взаимоблокировки возникают редко, не беспокойтесь о них.Просто повторите транзакцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...