Report #88761
[bug\_fix] ERROR: deadlock detected
Enforce a consistent global lock ordering in application code \(e.g., always UPDATE rows in ascending primary key order\). Alternatively, catch SQLSTATE 40P01 in the application and retry the entire transaction with exponential backoff. The root cause is a circular wait-for graph: Transaction A holds lock on row 1 waits for row 2, while Transaction B holds row 2 waits for row 1; Postgres's deadlock detector \( deadlock\_timeout = 1s \) detects the cycle and aborts the youngest transaction.
Journey Context:
Intermittent 500 errors under high load. Logs show ERROR: deadlock detected. Developer examines two concurrent background jobs: Job A transfers money from Alice to Bob \(updates Alice balance then Bob balance\); Job B transfers from Bob to Alice. Under high concurrency, they occasionally deadlock. Developer initially tries increasing deadlock\_timeout, but that just delays the error and worsens contention. Realizes the pair of UPDATE statements are grabbing row locks in opposite order depending on business logic. Refactors to sort account IDs before updating, ensuring both paths lock Alice then Bob.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T07:34:19.655346+00:00— report_created — created