Error handling for MySQL applications

Retry deadlocks and lock waits; reconnect on gone-away. Design for InnoDB concurrency.

InnoDB will sometimes ask the client to retry. Treating every SQL error as fatal pages humans for concurrency that worked as designed.

Transient errors

Code Meaning Action
1213 Deadlock; transaction rolled back Retry whole txn
1205 Lock wait timeout Retry or shorten txn
2006 / 2013 Connection gone Reconnect; retry txn
1040 / 1203 Too many connections Back off; fix pooling

Deadlock victims are chosen by InnoDB; your job is to retry the entire transaction with the same business intent, not to resume mid-statement.

Pattern

for attempt in 1..N:
  BEGIN
  try work → COMMIT → return
  on 1213/1205: ROLLBACK; sleep with jitter
  on connection loss: reconnect; retry

Rules:

  • Cap attempts (3–5) with jittered exponential backoff
  • Log SQLSTATE + truncated SQL for diagnostics
  • Never retry non-idempotent side effects without an idempotency key or outbox
  • Distinguish “retry forever” from “open a ticket” after N failures

Reduce deadlocks

  • Consistent table/row lock order across all code paths
  • Short transactions; no remote HTTP while holding locks
  • Indexed lookups instead of scans that lock unintended ranges
  • Prefer READ COMMITTED only when you understand the trade-offs vs default REPEATABLE READ

Put retry policy in one repository or unit-of-work layer so product code cannot forget.