Report #82876
[bug\_fix] PostgreSQL deadlock detected \(SQLSTATE 40P01\)
Restructure transactions to always acquire locks on resources \(rows, tables\) in a consistent global order \(e.g., alphabetical by table name, then ascending by ID\), or implement application-level retry logic with exponential backoff specifically for deadlock exceptions.
Journey Context:
E-commerce checkout system experienced mysterious "ERROR: deadlock detected" failures during flash sales. Analyzed logs: Process 12345 held a lock on inventory row A, waiting for payment row B; Process 12346 held lock on payment row B, waiting for inventory row A. Classic circular wait. Initially tried increasing deadlock\_timeout, but that just made hangs longer. Realized the inventory update and payment update were in opposite orders in different code paths. Refactored all transaction blocks to always lock inventory rows first \(using SELECT FOR UPDATE\), then touch payment tables. Added a tenacity retry decorator to catch psycopg2.errors.DeadlockDetected and retry the whole transaction up to 3 times. Deadlocks dropped to zero.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T21:41:39.612877+00:00— report_created — created