Serializable isolation rejects unsafe histories. The application must safely repeat the complete decision rather than retrying one stale statement.
Serializable Transaction Retry
A serialization abort invalidates the whole decision, not only the statement that noticed it.
async function serializable<T>(run: (db: Client) => Promise<T>) {
for (let attempt = 1; attempt <= 4; attempt++) {
const db = await pool.connect()
try {
await db.query('BEGIN ISOLATION LEVEL SERIALIZABLE')
const result = await run(db) // repeat the entire decision
await db.query('COMMIT')
return result
} catch (error) {
await db.query('ROLLBACK').catch(() => {})
if (sqlState(error) !== '40001' || attempt === 4) throw error
await sleep(Math.random() * 20 * attempt)
} finally { db.release() }
}
throw new Error('unreachable')
}Invariant: Every attempt recomputes the business decision from a fresh serializable snapshot and stops inside a bounded retry budget.
Use when: A PostgreSQL transaction protects a cross-row invariant and may be aborted as non-serializable.
Why this boundary matters
Retrying only the failed statement preserves decisions made from an invalid snapshot. The complete read-decide-write unit must execute again.
Failure policy
| Boundary | Action |
|---|---|
| SQLSTATE 40001 | Roll back and retry the complete transaction with jitter |
| Deadlock 40P01 | Retry only when the operation is safe and budget remains |
| Unique violation | Return a domain conflict unless explicitly classified otherwise |
| Commit outcome ambiguous | Reconcile by stable command identity |
| Deadline exhausted | Fail without another attempt |
Trade-offs
Serializable isolation protects multi-row and predicate invariants but can abort transactions under contention. Retries add latency and load, so repeated conflicts should trigger redesign rather than larger limits.
Decision rule: Use it when invalid cross-row state costs more than bounded retries, and keep external side effects outside the retrying transaction.
Further reference
Browse all engineering snippets · Read the architecture guide