Scenario · Locks & Transactions
Deadlock from inconsistent lock ordering
A sandboxed PostgreSQL incident — investigate with your own tools, submit a fix, and get deterministic Detect / Fix / Trap scoring.
L3 · 10–15 min · runs locally in Docker
Launch
Start this scenario
Boot it in a real PostgreSQL sandbox and investigate with psql, EXPLAIN and pg_stat_statements.
ride postgres start stage-02/03-deadlockPart of these paths
Show the postmortem & investigation hints spoilers
Deadlock from inconsistent lock ordering Type: incident simulation · Topic: Locks & Transactions · Level: L3 · Duration: 10–15 min Launch: ride postgres start stage-02/03-deadlock POSTMORTEM (root cause · how it was found · the fix · lesson) Root cause: two transactions updated the same two accounts in opposite orders — one did account 1 then 2, the other did 2 then 1. Each held one row and waited for the other, a cycle PostgreSQL resolves by aborting one transaction with `ERROR: deadlock detected`. The database did its job; the bug is in the application's lock ordering. How it was found: the deadlock error appeared in the server log; inspecting the transactions showed the opposite update orders. The fix: make every transaction take row locks in a consistent order — e.g. always update accounts in ascending id order: BEGIN; UPDATE accounts SET balance = balance - 100 WHERE id = 1; UPDATE accounts SET balance = balance + 100 WHERE id = 2; COMMIT; With a global ordering, a cycle is impossible. Lesson: deadlocks are an application design problem, not a server tuning knob. Acquire locks in a consistent order (and keep transactions short). Retrying the same inconsistent order just reproduces the deadlock. INVESTIGATION HINTS (the staged path to diagnose and fix) 1. The server log shows `ERROR: deadlock detected`. A deadlock means two transactions grabbed the same rows in opposite order and waited on each other. 2. Look at the deadlock detail: one transaction locked account 1 then wanted 2, the other locked 2 then wanted 1. Inspect pg_stat_activity / pg_locks while it reproduces. 3. The fix isn't a database setting — it's consistent lock ordering. Always update the accounts in the same order (ascending id) inside every transaction, and they can't deadlock.