Добавить в корзинуПозвонить
Найти в Дзене
CODERIKK

🔹 Deadlock в БД (база данных): что это и как избежать

🔹 Почему две транзакции могут взаимно блокироваться (конфликт)? 🔸 Locks нужны, чтобы защитить данные от одновременных изменений. Deadlock — это ситуация, когда транзакция A держит lock на ресурсе X и ждёт Y, а транзакция B держит lock на Y и ждёт X, в результате обе висят и не могут продолжить. Конфликт возникает на пересечении ресурсов. 🔸 Последствие — тормоза и откаты: СУБД обнаружит deadlock и убьёт одну транзакцию (victim), чтобы снять циклическую блокировку. При уровне изоляции SERIALIZABLE шанс конфликтов выше из‑за более жёстких locks. 🔸 Практические способы предотвратить: держать транзакции короткими, соблюдать одинаковый порядок блокировок для всех потоков, добавить индексы чтобы избежать больших сканирований, понижать изоляцию при допустимости, ловить ошибку deadlock и ретраить транзакцию. -- Т1 BEGIN; UPDATE accounts SET balance=balance-10 WHERE id=1; UPDATE accounts SET balance=balance+10 WHERE id=2; COMMIT; -- Т2 BEGIN; UPDATE accounts SET balance=balance-10 WHERE

🔹 Deadlock в БД (база данных): что это и как избежать

🔹 Почему две транзакции могут взаимно блокироваться (конфликт)?

🔸 Locks нужны, чтобы защитить данные от одновременных изменений. Deadlock — это ситуация, когда транзакция A держит lock на ресурсе X и ждёт Y, а транзакция B держит lock на Y и ждёт X, в результате обе висят и не могут продолжить. Конфликт возникает на пересечении ресурсов.

🔸 Последствие — тормоза и откаты: СУБД обнаружит deadlock и убьёт одну транзакцию (victim), чтобы снять циклическую блокировку. При уровне изоляции SERIALIZABLE шанс конфликтов выше из‑за более жёстких locks.

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

-- Т1

BEGIN;

UPDATE accounts SET balance=balance-10 WHERE id=1;

UPDATE accounts SET balance=balance+10 WHERE id=2;

COMMIT;

-- Т2

BEGIN;

UPDATE accounts SET balance=balance-10 WHERE id=2;

UPDATE accounts SET balance=balance+10 WHERE id=1;

COMMIT;

📚 Коротко: избегайте циклического порядка захвата locks, делайте транзакции короткими и реализуйте retry при deadlock.

#CODERIKK #Interview #Middle

➡️ Мы в Telegram - Сетке - Дзен

Буду рад вашей реакции здесь⬇️