Report #86818
[bug\_fix] Postgres serialization failure in SERIALIZABLE isolation \(SQLSTATE 40001\)
Implement automatic retry logic in the application for SQLSTATE 40001 when using SERIALIZABLE or REPEATABLE READ isolation levels, as these errors are expected "fail fast" behaviors for serializable anomalies rather than configuration issues.
Journey Context:
A developer switches their ticket booking system to use SET TRANSACTION ISOLATION LEVEL SERIALIZABLE to prevent race conditions where two users book the same last seat. Under load, they see frequent ERROR: could not serialize access due to read/write dependencies among transactions with SQLSTATE 40001, causing HTTP 500 errors. They initially believe Postgres is broken or that they need to tune locks. The rabbit hole reveals that unlike READ COMMITTED \(which uses MVCC and blocking\), SERIALIZABLE uses a predicate locking system and a serialization graph to detect anomalies like write skew. When the graph shows a cycle \(an unserializable situation\), Postgres aborts one transaction with SQLSTATE 40001 to maintain correctness. This is by design. The fix is a retry decorator that catches this specific SQLSTATE, rolls back, and retries the transaction with exponential backoff. This implements optimistic concurrency control acceptable for serializable correctness, where contention is low enough that retries are rare, but correctness is guaranteed.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T04:18:40.217763+00:00— report_created — created