Java Interview Questions

MySQL Transaction Isolation Levels and MVCC Explained

"Explain MySQL's transaction isolation levels and how MVCC implements Repeatable Read."

Why Interviewers Ask This

Isolation levels plus MVCC is THE MySQL deep-dive question at senior backend interviews. It tests whether you've internalized what "isolation" actually means at the storage-engine level — most candidates can list the four levels but few can explain the Read View mechanism that makes RR work.

How to Answer

  1. 1

    Start with the four SQL-standard levels and what each prevents: Read Uncommitted (allows dirty reads), Read Committed (no dirty reads, allows non-repeatable reads), Repeatable Read (no non-repeatable reads, may allow phantom reads per standard), Serializable (full locking, no anomalies).

  2. 2

    Define each anomaly: dirty read sees uncommitted data; non-repeatable read gets different values for the same row across two reads in one transaction; phantom read gets different row sets matching the same WHERE clause.

  3. 3

    State MySQL specifics: InnoDB default is Repeatable Read, and unlike the SQL standard, MySQL RR blocks phantom reads for snapshot reads via MVCC, and for current reads via gap locks and next-key locks.

  4. 4

    Explain MVCC: every row has hidden columns trx_id (transaction ID that last modified it) and roll_pointer (pointer to undo log entries forming a version chain). On snapshot read, InnoDB constructs a Read View — a snapshot of active transaction IDs at the moment of read (or transaction start for RR).

  5. 5

    Walk the visibility rules: a row version is visible if its trx_id < min active trx, or trx_id is the current transaction, or (trx_id < max trx AND trx_id not in active list). Otherwise follow the roll_pointer to the previous version. This gives each transaction a stable snapshot without blocking writers.

Sample Answer

SQL defines four isolation levels. Read Uncommitted allows reading uncommitted changes — "dirty reads". Read Committed prevents dirty reads but not "non-repeatable reads" — if transaction A reads a row twice and transaction B commits an update in between, A sees different values. Repeatable Read prevents non-repeatable reads — the same row returns the same value throughout the transaction — but the SQL standard still allows "phantom reads" where a range query returns different row counts. Serializable serializes everything with locks; it's correct but has terrible concurrency. InnoDB's default is Repeatable Read, and MySQL is unusual — it prevents phantom reads at RR too, using MVCC for snapshot reads and gap locks for locking reads. MVCC is how InnoDB avoids blocking readers with writers. Each row has two hidden columns: trx_id, the ID of the transaction that last modified it, and roll_pointer, pointing into the undo log at the previous version. Undo log entries chain together — every update pushes the old version onto the chain. On a snapshot read, InnoDB creates a Read View — under RR, the Read View is built once at the first read of the transaction and reused; under RC, a new Read View is built for every statement. The Read View stores the list of active (uncommitted) transaction IDs plus a low-water mark (min active) and high-water mark (max trx ID at that moment). Visibility rule: a row version is visible if its trx_id committed before the Read View was created — specifically, trx_id < low-water mark, OR trx_id == this transaction, OR (trx_id < high-water mark AND trx_id not in active list). If invisible, walk the roll_pointer chain to an older version and re-check. This gives each transaction a stable view of the database consistent with its Read View timestamp, without blocking writers. Current reads like SELECT ... FOR UPDATE don't use MVCC — they read the latest committed version and take row/gap locks to prevent concurrent modification.

Pro Tips

  • Make the "MySQL RR blocks phantom reads via MVCC + gap locks" point explicitly — many candidates miss that MySQL diverges from the standard.

  • Be able to draw the undo log chain and point at a trx_id being compared against the Read View.

  • Know the difference between snapshot read (SELECT) and current read (SELECT FOR UPDATE / UPDATE) — they use MVCC vs. locks respectively.

  • If the RC vs RR Read View distinction slips your mind, HireMe AI can surface "RR creates one Read View, RC creates one per statement" on the fly.

Frequently Asked Questions

Why does MySQL default to RR when most DBs default to RC?

Historical reasons around MySQL statement-based binlog replication needing RR to stay consistent. MySQL 8 with row-based binlog has made RC a viable default for many workloads.

How do gap locks prevent phantom reads?

Next-key locks (record lock + gap lock) cover both the matched rows and the gaps between them, so another transaction can't insert into the range you're reading.

Does MVCC affect performance?

Readers never block writers and vice versa, which is a big concurrency win. The cost is the undo log must retain versions until no Read View needs them — long-running transactions bloat undo.

Worried About Going Blank in Your Interview?

HireMe AI listens to your interview in real-time, detects questions, and generates instant answer suggestions — so you never freeze up again.

Try HireMe AI Free