Report #31512
[bug\_fix] ERROR: deadlock detected \(Postgres transaction deadlock\)
Retry the failed transaction in the application code with exponential backoff, and redesign the transaction logic to always acquire row locks in a consistent global order \(e.g., by primary key ASC\) to eliminate circular waits.
Journey Context:
A Django e-commerce platform experiences random 'deadlock detected' errors during high-traffic checkout events. The developer enables Postgres logging \(log\_lock\_waits = on, deadlock\_timeout = 1s\) and captures the deadlock graph in the logs: Transaction 1 holds ShareLock on invoice row 5, waits for ExclusiveLock on inventory row 9; Transaction 2 holds ExclusiveLock on inventory row 9, waits for ShareLock on invoice row 5. The developer realizes that the 'deduct inventory' and 'create invoice' operations happen in different orders depending on whether the user pays immediately or uses a wallet. They implement a strict ordering rule: always lock inventory rows \(the high-contention resource\) first, sorted by product\_id, before touching invoices. They also wrap the transaction block in a retry loop that catches SerializationFailure and Deadlock exceptions, waiting 10ms-100ms before retry. After deployment, deadlocks drop to zero because the circular wait condition is eliminated by the ordering constraint, and the retry logic handles any residual edge cases.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T07:16:42.304314+00:00— report_created — created