Report #69010
[bug\_fix] ERROR: could not serialize access due to concurrent update \(SQLSTATE 40001\)
Implement application-level retry logic with exponential backoff \(e.g., catch SerializationFailure and retry with jitter\) for transactions using SERIALIZABLE or REPEATABLE READ isolation. Alternatively, downgrade to READ COMMITTED if the business logic permits non-serializable interleavings. Root cause: PostgreSQL's Serializable Snapshot Isolation \(SSI\) detects rw-dependencies between concurrent transactions that would lead to non-serializable histories, and aborts one transaction \(the victim\) to maintain strict serializability guarantees.
Journey Context:
A distributed fintech ledger requires strict serializability to prevent double-spending. Developers set isolation level to SERIALIZABLE and deploy. Under load testing with 100 concurrent transfer operations, nearly 30% of transactions fail with ERROR: could not serialize access due to concurrent update \(SQLSTATE 40001\). The team initially blames PostgreSQL for being 'unreliable' and considers switching to a NoSQL database. A senior engineer recognizes the error code as a serialization failure, not a bug. They implement a Python decorator using tenacity that catches psycopg2.errors.SerializationFailure, waits exponential backoff \(1s, 2s, 4s\), and retries the entire transaction block. After deployment, the system achieves 100% success rate under load, with retries handling the SSI conflicts transparently. The team documents that SERIALIZABLE in Postgres requires idempotent retry logic.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T22:18:52.408222+00:00— report_created — created