Report #3778
[bug\_fix] ERROR: deadlock detected \(Postgres\)
Acquire row locks in a consistent global order \(e.g., \`ORDER BY id ASC\`\) across all code paths, or implement application-level retry loops for 40P01 errors.
Journey Context:
A payment processing system runs two concurrent batch jobs. Job A transfers from user 100 to user 200; Job B transfers from user 200 to user 100. Both use \`SELECT ... FOR UPDATE\` to lock rows. Job A locks row 100, then tries to lock 200. Simultaneously, Job B locks row 200, then tries to lock 100. Postgres detects the circular wait graph and aborts one transaction with 'deadlock detected'. The debugging involves tracing the application logs to find the opposite update orders. The fix standardizes all transfer functions to \`SELECT ... FOR UPDATE FROM accounts WHERE id IN \(src, dst\) ORDER BY id ASC\`, ensuring both jobs always attempt to lock the lower ID first, preventing the circular dependency entirely.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T18:12:03.961749+00:00— report_created — created