Skip to content

40001 — could not serialize access ​

PostgreSQL 40001 can reject a REPEATABLE READ target changed since its snapshot or a SERIALIZABLE dependency conflict; roll back and retry the complete transaction with fresh decisions, or return controlled failure.

Reproduce it ​

Two sessions. The -- [A] and -- [B] markers say who runs each statement, top to bottom.

sql
-- [A] open a snapshot and read the row
BEGIN ISOLATION LEVEL REPEATABLE READ;
SELECT balance FROM accounts WHERE id = 1;   -- sees 100

-- [B] change that same row and commit
UPDATE accounts SET balance = 150 WHERE id = 1;

-- [A] now try to write the row you read
UPDATE accounts SET balance = 200 WHERE id = 1;

A's target was changed after its snapshot, so its UPDATE fails with 40001. A cannot continue ordinary queries in the failed block. The complete Scenario includes immediate and waiting conflict branches; the lost-update example separately executes a successful fresh retry. Retry the full set of reads and decisions, with a bound or controlled failure. A stale human edit can require reconsideration, and database rollback does not undo external effects. Retrying is not guaranteed to succeed.

Run it yourself ​

This is the lead example on the Repeatable Read lesson, rendered there as a verified transcript against a real database. The retry loop that turns this failure into a safe write lives in Retrying serialization failures, and Serializable is the stricter level that raises the same 40001 for a wider set of conflicts.

The MySQL side ​

InnoDB uses locking SERIALIZABLE reads inside explicit transactions. Conflicts can wait and then succeed or fail; this PostgreSQL schedule does not predict every MySQL outcome. MySQL deadlock errno 1213 has SQLSTATE 40001; row-lock timeout 1205 has different rollback scope. Check the engine and driver representation before selecting recovery.

MIT Licensed · Every transcript on this site was generated by a real database run against MySQL 8.4.11 and PostgreSQL 18.6 at 8fa27b8; shared YAML has an independent psycopg/PyMySQL check.