Report #13629
[bug\_fix] ERROR: could not serialize access due to read/write dependencies among transactions \(SQLSTATE 40001\)
Implement application-level retry logic with exponential backoff specifically for SQLSTATE 40001 errors. The transaction must be rolled back and retried from the beginning. Root cause: Serializable Snapshot Isolation \(SSI\) detected a rw-dependency cycle between concurrent transactions that would violate serializable isolation guarantees.
Journey Context:
A financial ledger application using \`SET TRANSACTION ISOLATION LEVEL SERIALIZABLE\` to ensure strict correctness started throwing 'could not serialize access' errors under moderate load. The developer knew Serializable isolation prevents anomalies but didn't expect errors on read-only conflicts. Investigation of PostgreSQL logs revealed the SSI \(Serializable Snapshot Isolation\) implementation detects rw-dependencies. Transaction A read account X, then wrote account Y. Concurrent Transaction B read account Y \(the old version\), then tried to write account X. This creates a cycle: A reads X, B will write X; B reads Y, A writes Y. Postgres detects this as a potential anomaly and aborts one transaction with SQLSTATE 40001. The debugging involved checking \`pg\_stat\_database\` for \`conflicts\_serializable\`, analyzing the transaction patterns, and realizing that unlike Read Committed, Serializable requires retry loops. The fix works because Serializable isolation is optimistic; it assumes conflicts are rare and validates at commit time, aborting if the serialization graph has cycles. Application retries are the mandated mechanism to handle these inevitable aborts.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T19:16:38.279973+00:00— report_created — created