Report #103417
[bug\_fix] PostgreSQL ERROR: deadlock detected \(40P01\)
Make all code paths that update the same tables acquire row locks in a consistent order \(e.g., always lock account then ledger then notification\), and wrap the operation in a small retry loop that catches 40P01 and reruns the transaction. Also keep transactions short so locks are not held during unrelated I/O.
Journey Context:
Under concurrent load the API started returning 500s with PostgreSQL's ERROR: deadlock detected. The logs showed two transactions each waiting for a row lock the other held. The first transaction updated row A then row B; a second background job, written by a different team, updated row B then row A. Both were tiny and looked correct in isolation. Adding a retry masked the problem for a day, but deadlocks kept happening at higher volume because the lock-order inversion remained. The fix was to define a canonical lock order for related tables and refactor the background job to follow it. A thin retry loop was kept only for unavoidable serialization failures. Once lock ordering was consistent, deadlocks disappeared entirely.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-07-11T04:22:09.269801+00:00— report_created — created