Report #47593
[bug\_fix] Postgres ERROR: deadlock detected
Enforce a strict global ordering on table access \(e.g., alphabetically: inventory, then orders, then users\) across all transactions, and implement application-level retry logic with exponential backoff for deadlock errors \(SQLSTATE 40P01\). Root cause is a circular wait where Transaction A holds Lock 1 and waits for Lock 2, while Transaction B holds Lock 2 and waits for Lock 1.
Journey Context:
An e-commerce checkout endpoint intermittently fails with ERROR: deadlock detected. Logs show two concurrent transactions: Tx1 updates inventory \(locks inventory row 5\), then tries to update orders \(needs orders row 10\). Simultaneously, Tx2 updates orders \(locks orders row 10\), then tries to update inventory \(needs inventory row 5\). PostgreSQL's deadlock detector wakes up, identifies the cycle \(Tx1→Tx2→Tx1\), and aborts Tx1 with the error. Debugging reveals the inventory update and order creation were in different code paths with no enforced order. Initially trying to catch and retry in the database layer fails because the transaction is already aborted. Solution requires both: \(1\) refactoring all checkout code to always update inventory BEFORE orders \(alphabetical ordering\), preventing the cycle, and \(2\) adding try/catch in the application to retry the entire transaction block on 40P01 errors for edge cases.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T10:21:48.123183+00:00— report_created — created