Lock Deadlock Prevention
title: Prevent Deadlocks with Consistent Lock Ordering impact: MEDIUM-HIGH impactDescription: Eliminate deadlock errors, improve reliability tags: deadlocks, locking, transactions, ordering
Section titled “title: Prevent Deadlocks with Consistent Lock Ordering impact: MEDIUM-HIGH impactDescription: Eliminate deadlock errors, improve reliability tags: deadlocks, locking, transactions, ordering”Prevent Deadlocks with Consistent Lock Ordering
Section titled “Prevent Deadlocks with Consistent Lock Ordering”Deadlocks occur when transactions lock resources in different orders. Always acquire locks in a consistent order.
Incorrect (inconsistent lock ordering):
-- Transaction A -- Transaction Bbegin; begin;update accounts update accountsset balance = balance - 100 set balance = balance - 50where id = 1; where id = 2; -- B locks row 2
update accounts update accountsset balance = balance + 100 set balance = balance + 50where id = 2; -- A waits for B where id = 1; -- B waits for A
-- DEADLOCK! Both waiting for each otherCorrect (lock rows in consistent order first):
-- Explicitly acquire locks in ID order before updatingbegin;select * from accounts where id in (1, 2) order by id for update;
-- Now perform updates in any order - locks already heldupdate accounts set balance = balance - 100 where id = 1;update accounts set balance = balance + 100 where id = 2;commit;Alternative: use a single statement to update atomically:
-- Single statement acquires all locks atomicallybegin;update accountsset balance = balance + case id when 1 then -100 when 2 then 100endwhere id in (1, 2);commit;Detect deadlocks in logs:
-- Check for recent deadlocksselect * from pg_stat_database where deadlocks > 0;
-- Enable deadlock loggingset log_lock_waits = on;set deadlock_timeout = '1s';Reference: Deadlocks