ТранзакцииПродвинутый
Deadlock (взаимная блокировка)
Ситуация, когда две транзакции ждут блокировок друг друга и не могут продолжить.
Синтаксис
-- Защита от дедлоков: одинаковый порядок блокировок SELECT * FROM ... WHERE id IN (...) ORDER BY id FOR UPDATE;
Объяснение
Дедлок: транзакция A блокирует строку 1, транзакция B блокирует строку 2. A хочет строку 2, B хочет строку 1 — оба ждут вечно.
PostgreSQL автоматически обнаруживает дедлоки и откатывает одну из транзакций с ошибкой.
Как избежать:
- Всегда блокируй ресурсы в одном порядке
- Используй SELECT ... FOR UPDATE SKIP LOCKED для очередей
- Держи транзакции короткими
Пример
-- Безопасная очередь задач SELECT * FROM tasks WHERE status = 'pending' ORDER BY created_at LIMIT 1 FOR UPDATE SKIP LOCKED;
Связанные термины
Анекдоты по теме
Начинающий DBA удалил таблицу. Шеф спрашивает: — Бэкап сделал? — А что это? — Уволю. — Может, ROLLBACK? — А он был BEGIN? — Не помню. — Тогда точно уволю.
— Что делать, если случайно запустил DELETE без WHERE? — Плакать. Если повезёт и была транзакция — сделать ROLLBACK. Если не повезло — доставать бэкап.
Программист написал DELETE без WHERE. Через секунду он уже писал резюме.