Report #64556
[bug\_fix] ERROR: deadlock detected
Ensure all concurrent transactions acquire row locks in a consistent, predetermined order \(e.g., always lock table A before table B, or sort rows by primary key before updating\). Alternatively, implement an application-level retry loop that catches deadlock errors \(SQLSTATE 40P01\) and re-executes the failed transaction. The root cause is a cyclic dependency where Transaction 1 holds a lock on Row X and waits for Row Y, while Transaction 2 holds a lock on Row Y and waits for Row X.
Journey Context:
You have a Python e-commerce app processing inventory and order updates. Under high load during a flash sale, you start seeing \`psycopg2.errors.DeadlockDetected\` exceptions. The trace shows two concurrent API requests: one updating the \`inventory\` table for product\_id 5 and then inserting into \`orders\`, and another updating \`inventory\` for product\_id 5 but inserting into \`orders\` first. You examine the logs and realize Transaction A updates inventory row 5 \(acquiring lock\), then tries to insert into orders \(needs lock on orders index\). Transaction B inserts into orders \(acquires lock on index\), then tries to update inventory row 5 \(blocked by A\). You fix it by refactoring the code so that any transaction that touches both tables always updates the \`inventory\` table first, and within inventory updates, always processes rows sorted by \`product\_id\`. You also wrap the transaction block in a retry decorator that catches 40P01 and retries up to 3 times with exponential backoff, eliminating user-facing errors.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T14:50:43.944234+00:00— report_created — created