Report #90287
[bug\_fix] ERROR: deadlock detected \(PostgreSQL transaction deadlock\)
Implement a strict lock acquisition order \(e.g., always lock tables or rows alphabetically by primary key\) to prevent circular waits, or wrap transactions in application-level retry logic that catches SQLSTATE 40P01 \(deadlock\_detected\) and retries with exponential backoff. PostgreSQL automatically detects deadlocks and kills the "victim" transaction, but the application must handle the rollback and retry.
Journey Context:
An e-commerce platform experiences intermittent "deadlock detected" errors during flash sales. Analysis of two concurrent transactions reveals: Transaction A updates inventory for Product X \(row A\) then creates an Order \(row B\); Transaction B updates shipping status for Order \(row B\) then decrements inventory for Product X \(row A\). Under high concurrency, T1 holds lock on A waiting for B, while T2 holds lock on B waiting for A, forming a cycle. PostgreSQL detects this after 1 second \(default deadlock\_timeout\) and aborts T2 with ERROR: deadlock detected. The application was not catching this exception, causing a 500 error. The fix involves reordering T2 to always acquire the inventory lock \(row A\) before the order lock \(row B\), ensuring a partial order and preventing cycles. Additionally, a retry decorator is added to catch OperationalError with SQLSTATE 40P01 and retry up to 3 times with jitter.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T10:08:22.037872+00:00— report_created — created