Report #88157
[bug\_fix] could not serialize access due to concurrent update \(SQLSTATE 40001\)
Catch SQLSTATE 40001 \(serialization\_failure\) and retry the entire transaction from the beginning with exponential backoff. Root cause: PostgreSQL's Serializable isolation level uses Serializable Snapshot Isolation \(SSI\) which detects rw-dependencies between concurrent transactions; when a conflict is detected, one transaction is aborted with error 40001 to prevent serialization anomalies, requiring application-level retry.
Journey Context:
You implement strict consistency checks using \`SERIALIZABLE\` isolation level in a financial application to prevent double-spending. Under load tests, the application throws frequent \`40001\` errors: \`could not serialize access due to read/write dependencies among transactions\`. The initial assumption is that this indicates a bug in PostgreSQL. However, investigation reveals this is the intended behavior of Serializable Snapshot Isolation \(SSI\). When two concurrent transactions read the same data and then one writes to it, creating a rw-dependency cycle, PostgreSQL aborts one transaction to prevent serialization anomalies. The application was treating these as fatal errors. The correct approach is to implement application-level retry logic specifically for SQLSTATE 40001. You wrap the transactional code in a retry loop \(e.g., using the \`tenacity\` library or a custom decorator\) that catches \`psycopg2.errors.SerializationFailure\` and retries with exponential backoff \(e.g., 1ms, 2ms, 4ms, up to 100ms\). This handles the contention gracefully without data corruption, as the failed transaction is rolled back and can be safely retried.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T06:33:14.204367+00:00— report_created — created