Report #93561
[bug\_fix] ERROR: could not serialize access due to concurrent update \(SQLSTATE 40001\)
Implement application-level retry logic with exponential backoff specifically for SQLSTATE 40001 \(serialization\_failure\), as this error is expected under Serializable Snapshot Isolation \(SSI\) when the system detects potential anomalies, not a bug requiring code changes.
Journey Context:
A financial trading platform began throwing "ERROR: could not serialize access due to concurrent update" errors after switching the database isolation level from READ COMMITTED to SERIALIZABLE to prevent race conditions in account balance transfers. The errors occurred under high concurrency when two transactions accessed the same account rows. Initial investigation suggested a locking bug, but pg\_locks showed no deadlocks. The error code was SQLSTATE 40001 \(serialization\_failure\), not 40P01 \(deadlock\). Research into PostgreSQL's Serializable Snapshot Isolation \(SSI\) revealed that Postgres tracks rw-dependencies between transactions. When it detects a cycle or dangerous structure that could lead to non-serializable behavior, it aborts one transaction with this error to maintain serializability guarantees. This is normal behavior for SSI, not a configuration error. The fix required changing the application's error handling: instead of treating 40001 as a fatal error, the service was updated to catch this specific SQLSTATE and retry the entire transaction with exponential backoff \(using a library like tenacity\). This accepts that high-contention serializable transactions may need several attempts to commit successfully.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T15:37:41.630686+00:00— report_created — created