Report #85069
[bug\_fix] Postgres "deadlock detected" \(SQLSTATE 40P01\)
Enforce consistent lock acquisition order \(e.g., sort row IDs before updating\), or implement application-level retry logic for the aborted transaction. Root cause: Two transactions acquire locks on rows in opposite order \(A locks row 1 then 2, B locks row 2 then 1\), creating a circular wait graph that Postgres detects and breaks by aborting one.
Journey Context:
A Java Spring Boot inventory service deadlocks under load. Thread A updates stock for Warehouse-X then Warehouse-Y. Thread B updates Warehouse-Y then Warehouse-X. Postgres logs show 'deadlock detected' and rolls back Thread B. Developer adds naive retry logic, but deadlocks continue during flash sales. Checking \`pg\_locks\` reveals the circular dependency: A holds ShareLock on X waiting for Y, B holds ShareLock on Y waiting for X. The fix works because by sorting warehouse IDs \(lowest first\) in the application code before starting the transaction, both threads attempt to lock X before Y. The first to lock X proceeds; the second blocks on X \(waiting linearly\), eliminating the circular wait. Postgres no longer detects a deadlock because the wait graph is acyclic.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T01:22:17.680688+00:00— report_created — created