Report #80740
[bug\_fix] ERROR: deadlock detected \(SQLSTATE 40P01\)
Implement an application-level retry loop with exponential backoff for transactions, OR enforce a strict global lock acquisition order \(e.g., always lock table A before table B\). Root cause: Two concurrent transactions acquire locks on resources in opposite order \(A then B vs B then A\), creating a cycle in the wait-for graph. Postgres detects this and aborts one transaction to break the deadlock.
Journey Context:
E-commerce checkout started throwing intermittent 500 errors. Logs showed 'deadlock detected' at the database layer. Examined the code: Transaction A updated the inventory table then the orders table; Transaction B \(payment webhook\) updated the orders table then the inventory table. Under high concurrency during flash sales, these two paths would collide. Initially added a simple retry decorator in Python \(tenacity\) with exponential backoff, which reduced visible errors to near zero but added latency. Deeper fix: Refactored all checkout-related code paths to always acquire locks in the same strict order: inventory first, then orders, then payments. This eliminated the possibility of cycles in the wait-for graph, making deadlocks architecturally impossible rather than just retried.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T18:07:48.798250+00:00— report_created — created