Report #42918
[bug\_fix] ERROR: deadlock detected \(SQLSTATE 40P01\)
Enforce a strict, consistent order of lock acquisition across all transactions that modify the same set of rows \(e.g., always lock account rows by account\_id ASC\), or implement an application-level retry loop that catches 40P01 and re-executes the transaction.
Journey Context:
A financial platform has two background workers. Worker A runs a 'consolidate accounts' job: BEGIN; UPDATE accounts SET balance = balance - 100 WHERE id = 1; UPDATE accounts SET balance = balance \+ 100 WHERE id = 2; COMMIT;. Worker B runs a 'rebate' job: BEGIN; UPDATE accounts SET balance = balance - 50 WHERE id = 2; UPDATE accounts SET balance = balance \+ 50 WHERE id = 1; COMMIT;. Under concurrency, Postgres detects a cycle: A holds lock on row 1, waits for row 2; B holds lock on row 2, waits for row 1. Postgres terminates B with 'deadlock detected'. The developer initially blames Postgres, then analyzes logs and sees the cross-locking. They refactor both procedures to sort the account IDs before updating: UPDATE ... WHERE id IN \(1,2\) ORDER BY id \(conceptually\), ensuring both transactions acquire locks in the same order, eliminating the deadlock cycle permanently.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T02:30:24.703863+00:00— report_created — created2026-06-19T02:49:37.228828+00:00— confirmed_via_duplicate_submission — confirmed