Two transactions politely wait for each other to let go — and so neither one ever does.
A deadlock is a standoff. Transaction T1 holds a lock on row A and now wants row B. Meanwhile T2 holds B and wants A. Each is blocked waiting for a lock the other refuses to release. They will wait forever.
The database draws a wait-for graph: an edge from every blocked transaction to whoever holds the lock it wants. When that graph contains a cycle, a deadlock exists. The engine can't satisfy everyone, so it picks a victim, rolls it back, and lets the survivor proceed. A "storm" is many such cycles forming at once under heavy contention.
The lock manager tracks who holds each lock and who is queued for it. On every grant request — or on a periodic timer — it walks the wait-for graph. A cycle means deadlock; the engine rolls back the cheapest victim, often the youngest transaction or the one holding the fewest locks, and returns a deadlock error the client should retry.
# Wait-for graph deadlock detection (cycle search)
def has_deadlock(waits_for):
# waits_for[t] = set of transactions t is blocked behind
WHITE, GREY, BLACK = 0, 1, 2
color = {t: WHITE for t in waits_for}
def dfs(t):
color[t] = GREY
for u in waits_for.get(t, ()):
if color[u] == GREY: # back-edge => cycle
return True
if color[u] == WHITE and dfs(u):
return True
color[t] = BLACK
return False
return any(color[t] == WHITE and dfs(t) for t in waits_for)
| Property | Detail |
|---|---|
| Detection | Cycle search over the wait-for graph, O(V + E) per scan |
| Resolution | Roll back one victim — its work is lost and must retry |
| Throughput | Storms waste CPU on doomed work; tail latency spikes |
| Signals | Rising deadlocks/sec, retry rate, lock-wait time |
Two transfers run at once. T1 does debit(A); credit(B); T2 does debit(B); credit(A). T1 locks A, T2 locks B. Now T1 waits for B and T2 waits for A — a 2-cycle. The detector picks T2 as victim, rolls it back, and T1 completes. The fix: have both transfers lock accounts in account-id order, so both grab A first and one simply queues behind the other — no cycle.
1. What graph structure proves a deadlock exists?
2. What single discipline prevents most deadlocks?
Coach note: if a pick doesn't land, give it another pass — the reasoning is what sticks.