Report #92159
[bug\_fix] Serializable isolation conflict \(40001\)
Implement application-level retry logic with exponential backoff for transactions that fail with serialization\_failure \(SQLSTATE 40001\). Root cause is Serializable Snapshot Isolation \(SSI\) detecting rw-dependencies that would violate serializability, aborting one transaction to preserve correctness.
Journey Context:
Your fintech app uses PostgreSQL's SERIALIZABLE isolation to prevent race conditions in fund transfers. Suddenly, legitimate concurrent transfers fail with 'ERROR: could not serialize access due to concurrent update'. You check \`pg\_stat\_database\` and see high \`conflicts\` count. You initially think it's a deadlock, but the error code is 40001 \(serialization\_failure\), not 40P01 \(deadlock\). You research SSI \(Serializable Snapshot Isolation\) and realize Postgres tracks rw-dependencies between transactions. When transaction A reads X then writes Y, and B reads Y then writes X, it's a cycle that would violate serializability. Unlike READ COMMITTED, SSI aborts one transaction to preserve correctness. The fix isn't to 'fix' the SQL, but to make the application retry transactions that get this error. You wrap your transfer logic in a retry loop with exponential backoff \(using tenacity or similar\), catching \`psycopg2.errors.SerializationFailure\`. Now when conflicts occur, the loser retries automatically, maintaining correctness without data corruption.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T13:16:48.058522+00:00— report_created — created