Report #70560
[bug\_fix] could not serialize access due to concurrent update \(SQLSTATE 40001\)
Catch SQLSTATE 40001 \(serialization\_failure\) and retry the transaction immediately with exponential backoff. This is expected behavior in SERIALIZABLE isolation; unlike deadlock, this occurs when the system detects a read-write dependency that could violate serializability. To reduce contention, minimize transaction duration, reduce the number of rows read/written, or use advisory locks to serialize access to hot rows explicitly.
Journey Context:
A financial transfer service uses \`SET TRANSACTION ISOLATION LEVEL SERIALIZABLE\` to prevent double-spending via write skew. Under load testing, transactions begin failing with 'could not serialize access due to read/write dependencies'. The developer initially confuses this with deadlock \(40P01\) but notices the SQLSTATE is 40001. Checking PostgreSQL logs, they see details about 'read-write dependencies between transactions'. The developer learns that PostgreSQL uses Serializable Snapshot Isolation \(SSI\) which tracks read dependencies and aborts transactions when anomalies are detected. They implement a retry loop in the application code specifically for 40001 errors, allowing the transaction to succeed on the second or third attempt. They also refactor to use \`SELECT ... FOR UPDATE\` on the balance rows to promote to predicate locks, reducing SSI aborts.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T01:01:10.747863+00:00— report_created — created