Report #83149
[bug\_fix] ERROR: deadlock detected \(40P01\)
Enforce consistent lock acquisition order \(e.g., always update rows ordered by primary key\) and implement application-level retry logic with exponential backoff. Root cause: Circular wait between two transactions where each holds a lock the other needs; PostgreSQL detects and kills one transaction to break the deadlock, but the application must handle the retry.
Journey Context:
An inventory system processes orders. Transaction A decrements stock for SKU-123 then SKU-456. Transaction B decrements SKU-456 then SKU-123. Under load, logs fill with 'deadlock detected'. The developer initially adds random sleeps, which only reduces frequency. Querying pg\_locks during a test shows Transaction A holds a lock on SKU-123 and waits for SKU-456, while B holds SKU-456 and waits for 123—a classic circular dependency. The fix involves refactoring the code to sort SKUs by ID before updating, ensuring both transactions acquire locks in identical order. This removes the possibility of circular wait. They also wrap the operation in a retry decorator that catches 40P01 and retries up to 3 times with jitter, handling edge cases where deadlocks might still occur from other code paths.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T22:09:21.832901+00:00— report_created — created