3.2 KiB
3.2 KiB
title, description, tags
| title | description | tags |
|---|---|---|
| InnoDB Transaction Isolation Levels | Best practices for choosing and using isolation levels | mysql, transactions, isolation, innodb, locking, concurrency |
Isolation Levels (InnoDB Best Practices)
Default to REPEATABLE READ. It is the InnoDB default, most tested, and prevents phantom reads. Only change per-session with a measured reason.
SELECT @@transaction_isolation;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; -- per-session only
Autocommit Interaction
- Default:
autocommit=1(each statement is its own transaction). - With
autocommit=0, transactions span multiple statements untilCOMMIT/ROLLBACK. - Isolation level applies per transaction. SERIALIZABLE behavior differs based on autocommit setting (see SERIALIZABLE section).
Locking vs Non-Locking Reads
- Non-locking reads: plain
SELECTstatements use consistent reads (MVCC snapshots). They don't acquire locks and don't block writers. - Locking reads:
SELECT ... FOR UPDATE(exclusive) orSELECT ... FOR SHARE(shared) acquire locks and can block concurrent modifications. UPDATEandDELETEstatements are implicitly locking reads.
REPEATABLE READ (Default — Prefer This)
- Consistent reads: snapshot established at first read; all plain SELECTs within the transaction read from that same snapshot (MVCC). Plain SELECTs are non-locking and don't block writers.
- Locking reads/writes use next-key locks (row + gap) — prevents phantoms. Exception: a unique index with a unique search condition locks only the index record, not the gap.
- Use for: OLTP, check-then-insert, financial logic, reports needing consistent snapshots.
- Avoid mixing locking statements (
SELECT ... FOR UPDATE,UPDATE,DELETE) with non-lockingSELECTstatements in the same transaction — they can observe different states (current vs snapshot) and lead to surprises.
READ COMMITTED (Per-Session Only, When Needed)
- Fresh snapshot per SELECT; record locks only (gap locks disabled for searches/index scans, but still used for foreign-key and duplicate-key checks) — more concurrency, but phantoms possible.
- Switch only when: gap-lock deadlocks confirmed via
SHOW ENGINE INNODB STATUS, bulk imports with contention, or high-write concurrency on overlapping ranges. - Never switch globally. Check-then-insert patterns break — use
INSERT ... ON DUPLICATE KEYorFOR UPDATEinstead.
SERIALIZABLE — Avoid
Converts all plain SELECTs to SELECT ... FOR SHARE if autocommit is disabled. If autocommit is enabled, SELECTs are consistent (non-locking) reads. SERIALIZABLE can cause massive contention when autocommit is disabled. Prefer explicit SELECT ... FOR UPDATE at REPEATABLE READ instead — same safety, far less lock scope.
READ UNCOMMITTED — Never Use
Dirty reads with no valid production use case.
Decision Guide
| Scenario | Recommendation |
|---|---|
| General OLTP / check-then-insert / reports | REPEATABLE READ (default) |
| Bulk import or gap-lock deadlocks | READ COMMITTED (per-session), benchmark first |
| Need serializability | Explicit FOR UPDATE at REPEATABLE READ; SERIALIZABLE only as last resort |