Deadlocks на собеседовании системного аналитика
Карьерник — Duolingo для аналитиков: 10 минут в день тренируй SQL, Python, A/B, статистику, метрики и ещё 3 темы собеса. 1500+ вопросов в Telegram-боте. Бесплатно.
Содержание:
Зачем спрашивают на собесе SA
Deadlocks — частая production проблема. SA должен закладывать защиту в дизайн. На собесе SA: «как возникает deadlock», «как избежать».
Что такое deadlock
Две / больше транзакций ждут друг друга, никто не может продвинуться.
T1: захватил row A, пытается row B
T2: захватил row B, пытается row A
→ Deadlock. Никто не закончится.В БД: транзакция блокирует строку (UPDATE / SELECT FOR UPDATE), пока не закоммитит.
Условия Coffman
Для deadlock необходимы все 4:
- Mutual exclusion. Ресурс не может shared (только один владелец).
- Hold and wait. Транзакция держит ресурс и ждёт другой.
- No preemption. Нельзя забрать ресурс силой (только владелец release'ит).
- Circular wait. Замкнутый цикл ожидания.
Убрать любое условие — нет deadlock.
Detection vs prevention
Detection. БД мониторит граф ожидания. При обнаружении цикла — kill одну транзакцию (deadlock victim), возвращает ошибку.
PostgreSQL: ERROR: deadlock detected
MySQL InnoDB: ERROR 1213: Deadlock found
Oracle: ORA-00060Application должен handle: retry transaction.
Prevention. Архитектурно избежать.
- Lock ordering. Все транзакции захватывают locks в одном порядке.
- Timeouts. Ждать только N секунд, потом abort.
- Optimistic locking. Не lock'ать, а проверять version при commit. Конфликт → retry.
Большинство БД — detection (кому нужен, тот retry'ит).
Lock ordering
Главное правило для prevention:
# плохо
T1: lock(A); ...; lock(B);
T2: lock(B); ...; lock(A); # обратный порядок → deadlock
# хорошо
def transfer(a, b, amount):
first, second = sorted([a, b]) # детерминированный порядок
lock(first); lock(second)
a.balance -= amount
b.balance += amountВсе транзакции lock'ат в order.
Deadlock в распределённых системах
В микросервисах локальный БД-deadlock не покрывает все случаи.
Distributed deadlock. Два сервиса делают синхронные RPC друг к другу с blocking ресурсов.
Service A holds resource X, calls B
Service B holds resource Y, calls A
→ Distributed deadlockDetection распределённо сложно.
Решение. Async messaging вместо sync RPC. Saga вместо distributed transactions.
Частые ошибки
Application не handle deadlock errors. На kill victim — ошибка наружу. Должен быть retry с backoff.
Long-running транзакции. Дольше держат locks → больше шанс deadlock. Дробить.
Случайный порядок locks. Code в разных местах захватывает inconsistently. Convention обязательна.
Игнорировать timeouts. Без timeout транзакция зависает forever, если detection не сработала.
Optimistic locking без version check. В производственных update'ах — race condition.
Связанные темы
- ACID и уровни изоляции для SA
- Транзакции и MVCC для DE
- Идемпотентность API для SA
- 2PC vs Saga для SA
- Подготовка к собесу системного аналитика
FAQ
Можно ли deadlock в Postgres MVCC?
Да. Read-only запросы не блокируют (snapshot isolation), но UPDATE / SELECT FOR UPDATE — да.
Это официальная информация?
Нет. Статья основана на классике (Coffman 1971), документации Postgres / MySQL / Oracle.
Тренируйте системный анализ — откройте тренажёр с 1500+ вопросами для собесов.