@NubasLol

Как бороться с deadlock?

Пример ошибки


SQLSTATE[40P01]: Deadlock detected: 7 ERROR: deadlock detected
DETAIL: Process 3199799 waits for ShareLock on transaction 28066780; blocked by process 3199816.
Process 3199816 waits for ShareLock on transaction 28066777; blocked by process 3199799.
HINT: See server log for query details.
CONTEXT: while updating tuple (78846,29) in relation "notifications" (SQL: update "notifications" set "is_read" = 1, "updated_at" = 2023-02-01 12:26:05 where "notifications"."client_id" = 126473 and "notifications"."client_id" is not null)


sql

update "notifications"
set "is_read"    = 1,
    "updated_at" = 2023 - 02 - 01 12:26:05
where "notifications"."client_id" = 126473 and "notifications"."client_id" is not null


Явно в транзакцию ничего не оборачиваю. И вот совершенно не понимаю, как это дебажить и фиксить. Помогите :(
  • Вопрос задан
  • 700 просмотров
Решения вопроса 1
iMedved2009
@iMedved2009
Не люблю людей
update "notifications"
set "is_read"    = 1,
    "updated_at" = 2023 - 02 - 01 12:26:05
from ( select id from "notifications" where “client_id” = 126473 and "notifications"."client_id" is not null order by id for update) as t
where "notifications"."id" = t.id ;


Дедлоки при пакетных апдейтах.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@mitya_k
У тебя есть видимо множество update, которые пытаются обновить данную запись. Вариантов решения несколько:
  • Переписать бизнес логику, чтобы update шли последовательно, а не параллельно
  • На уровне приложения ловить быть готовым, что может прилететь ошибка deadlock и сделать повторный запрос или что-то другое в зависимости от бизнес-логики
  • И самый костыльный вариант это увеличить deadlock_timeout - это время сколько postgres ждет, в случае блокировок. Я бы это использовал только, как временный вариант
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы