AiTechWorlds
AiTechWorlds
University learning companion
Database Management Systems (DBMS) · Deadlocks: Detection, Prevention, and Recovery
An online shop has one item left. Two customers click Buy at almost the same time, and both requests read the old stock value. Use this lesson to identify the shared state, the possible race, the guarantee the system needs, and a test that would expose the bug.
Use this course-level map to place “Deadlocks: Detection, Prevention, and Recovery” in the larger system. It complements—not replaces—a topic-specific worked diagram.
Picture two trains on a single track rail network. Train A is sitting at Station X, waiting for the line between X and Y to clear. Train B is sitting at Station Y, waiting for the line between Y and X to clear.
Neither train will ever move. Both are waiting for the other. There is no resolution unless someone outside the system intervenes and moves one of the trains backward.
That is a deadlock. And it happens in databases dozens of times per day in any busy system.
A deadlock occurs when two or more transactions are each waiting for a lock held by another transaction in the group. No transaction can proceed they are all frozen, waiting indefinitely.
Transaction A holds: Lock on Row 1
Transaction A wants: Lock on Row 2
Transaction B holds: Lock on Row 2
Transaction B wants: Lock on Row 1
→ Circular wait. Neither can proceed.A deadlock can only occur when all four conditions hold simultaneously. These were identified by Edward Coffman in 1971:
| Condition | Meaning |
|---|---|
| Mutual Exclusion | A resource can only be held by one transaction at a time |
| Hold and Wait | A transaction holds resources while waiting for more |
| No Preemption | Resources cannot be forcibly taken from a transaction |
| Circular Wait | A circular chain of transactions exists, each waiting on the next |
Break any one of these conditions and deadlock becomes impossible.
Databases detect deadlocks by building a Wait For Graph (WFG):
Wait-For Graph — No Deadlock: Wait-For Graph — Deadlock Detected:
Txn A ──→ Txn B ──→ Txn C Txn A ──→ Txn B
↑ │
(no cycle = no deadlock) └──── Txn C ←─┘
(cycle A→B→C→A = deadlock!)The database's deadlock detector runs periodically (e.g., every 1 second in PostgreSQL) or on every lock wait. When a cycle is found, it selects one transaction as the victim and rolls it back.
PostgreSQL:
ERROR: deadlock detected
DETAIL: Process 12483 waits for ShareLock on transaction 7890;
blocked by process 12491.
Process 12491 waits for ShareLock on transaction 7889;
blocked by process 12483.
HINT: See server log for query details.MySQL:
ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transactionYour application must catch these errors and retry the transaction.
Always acquire locks in the same global order. If every transaction locks Row 1 before Row 2 before Row 3, a circular wait can never form.
-- WRONG: Transaction A locks orders then customers
-- Transaction B locks customers then orders
-- → Deadlock possible
-- CORRECT: Both transactions always lock in the same order
-- 1. Lock customers table first
-- 2. Then lock orders tableAcquire all needed locks at the start of the transaction. If any lock is unavailable, release all held locks and retry.
-- Acquire all locks in one shot
SELECT * FROM accounts WHERE id IN (1, 2) FOR UPDATE;
-- Now update safely — no incremental lock acquisition
UPDATE accounts SET balance = balance - 500 WHERE id = 1;
UPDATE accounts SET balance = balance + 500 WHERE id = 2;
COMMIT;Set a lock wait timeout. If a transaction waits too long, it is automatically aborted.
-- PostgreSQL: abort if waiting more than 3 seconds
SET lock_timeout = '3s';
-- MySQL: wait at most 5 seconds for a lock
SET innodb_lock_wait_timeout = 5;The Banker's Algorithm (Dijkstra, 1965) is a resource allocation strategy that only grants a resource if doing so leaves the system in a "safe state" a state from which all transactions can eventually complete.
It works by simulating resource allocation ahead of time:
If granting this lock would leave the system unable to
satisfy all remaining transactions → DENY the lock (wait)
If granting the lock still leaves a safe path to completion → GRANT itThis is used in operating systems and some specialized database environments. Most general purpose databases prefer detection + recovery because avoidance is too expensive to compute at high transaction rates.
When a deadlock is detected, the database must choose a victim transaction to roll back. Selection criteria typically include:
-- PostgreSQL: you can view lock conflicts in pg_locks
SELECT pid, wait_event_type, wait_event, query
FROM pg_stat_activity
WHERE wait_event IS NOT NULL;These habits dramatically reduce deadlock frequency in production systems:
Keep transactions short. The longer a transaction runs, the more time it holds locks and the more chances for a conflict.
Access tables in a consistent order. If one part of your app always updates orders before order_items, every part of your app should do the same.
Avoid user interaction inside transactions. Never wait for a user to click a button while holding a database lock.
Use SELECT ... FOR UPDATE deliberately. This escalates a read lock to a write lock immediately useful when you know you will update the row.
BEGIN;
SELECT balance FROM accounts WHERE id = 1 FOR UPDATE;
-- Now this row is exclusively locked — no other transaction can modify it
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;Implement retry logic. Deadlocks are a normal part of database operation. Your application must catch deadlock errors and retry.
import time
def transfer_funds(conn, from_id, to_id, amount, retries=3):
for attempt in range(retries):
try:
with conn.transaction():
conn.execute("UPDATE accounts SET balance = balance - %s WHERE id = %s", (amount, from_id))
conn.execute("UPDATE accounts SET balance = balance + %s WHERE id = %s", (amount, to_id))
return # success
except DeadlockError:
if attempt == retries - 1:
raise
time.sleep(0.1 * (attempt + 1)) # exponential backoffA deadlock is not a bug in your database. It is a sign that two transactions are competing over the same resources. The right response is always retry with intelligent backoff.
University learning companion
Database Management Systems (DBMS) · Deadlocks: Detection, Prevention, and Recovery
Complete the steps without looking at the answer first; record evidence rather than only a final result.
These are primary or established learning references for this subject. Check the relevant chapter or specification for the exact topic and version.
Get this course's notes on Telegram!
Free cheat sheets, summaries & practice exercises