#Что означает ошибка
deadlock detected
Две транзакции ждут друг друга. Обновляйте строки в одном порядке, укорачивайте транзакции и повторяйте при ошибке.
#Причины и признаки
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Разный порядок блокировок | Транзакции захватывают строки в разном порядке. | Унифицируйте порядок обновлений. |
| Долгие транзакции | Транзакции остаются открытыми надолго. | Сократите транзакции, не делайте внешние вызовы внутри. |
| Нет индекса | Массовые операции удерживают много строк. | Оптимизируйте запросы и блокировки по плану. |
| Нет повтора | Приложение не обрабатывает SQLSTATE 40P01. | Повторяйте всю отменённую транзакцию ограниченно. |
#Пошаговое решение
- Найдите участников взаимной блокировки
deadlock detected— это цикл ожиданий между транзакциями; PostgreSQL прерывает одну из них для разрыва цикла. Администратор найдёт в журнале PostgreSQL запись ERROR с именами процессов, запросами и объектами. Сохраните её вместе со временем возникновения; обычное ожидание блокировки — другая ошибка. - Проверьте порядок операций в приложенииСравните транзакции, которые меняют одни и те же строки/таблицы. Если первая обновляет A→B, а вторая B→A, приведите порядок к одному и тому же в коде. Сократите длительность транзакций: запросы к сети и ожидание действий пользователя не должны выполняться с открытой блокировкой.
- Добавьте повтор только отменённой транзакцииОбработчик PostgreSQL SQLSTATE
40P01должен отменить текущую транзакцию и может повторить всю логическую операцию ограниченное число раз после небольшой случайной задержки. Повтор должен быть безопасным для побочных эффектов и использовать новый транзакционный контекст. Простое увеличение lock_timeout не устраняет цикл. - Проверьте результат на нагрузочном сценарииНа тестовой базе воспроизведите параллельные операции и убедитесь, что конфликт либо исчезает, либо корректно обрабатывается с повтором. Не завершайте все соединения PostgreSQL и не отключайте проверку транзакций на рабочей базе. При повторении сохраните схемы запросов и журнал deadlock.
#Если проблема осталась
Если «PostgreSQL: ERROR: deadlock detected» повторяется, сохраните время, состояние подключения и точный текст ошибки. Не меняйте сразу несколько настроек — иначе станет трудно понять, какое действие повлияло на результат.