InnoDB Locking: Row Lock, Gap Lock, and Next-Key Lock
Fast recall
Quick revision
Core answer
Tests deep InnoDB knowledge.
This question differentiates candidates who understand why deadlocks happen and how to diagnose them from those who only know surface-level SQL.
Critical for fintech or high-concurrency applications.
Interview-ready guide
Interview answer
InnoDB's locking system is more complex than most developers expect because locks don't attach to rows — they attach to index entries. That distinction is the root cause of most unexpected deadlock and blocking behaviors in Spring Boot applications.
Row locks — locking index entries
- InnoDB row locks are placed on index entries, not physical rows — which means if a query filters on an unindexed column, InnoDB must examine all rows and lock the entire table's index entries to guarantee no matching row is modified concurrently
- Always filter on indexed columns in
SELECT ... FOR UPDATEandUPDATE WHERE— queries that fall back to table scans hold far more locks than necessary
Gap locks — protecting ranges
- A gap lock prevents other transactions from inserting into the gap between two existing index values — so
SELECT * FROM orders WHERE id BETWEEN 10 AND 20 FOR UPDATElocks not just rows 10-20, but the gaps between them, preventing any insert of id 11-19 from another transaction - Gap locks only exist under Repeatable Read; switching to Read Committed eliminates them, which reduces deadlock frequency in insert-heavy workloads
Next-key locks — the combination
- A next-key lock is a row lock plus a gap lock on the preceding gap — InnoDB's default locking mode under Repeatable Read combines both to prevent both row modification and phantom inserts in a scanned range
- This is why two transactions that read the same range and then insert into it deadlock: each holds a gap lock the other needs for its insert
When you see deadlocks in production, check SHOW ENGINE INNODB STATUS — the output shows the exact locks held and waited on by each transaction in the deadlock cycle.
InnoDB Locking: Row Lock, Gap Lock, and Next-Key Lock
Direct Answer
InnoDB uses three lock granularities: row locks protect individual rows, gap locks protect the space between index values to prevent phantom inserts, and next-key locks (the default) combine both to lock a row plus the gap before it. Next-key locks are InnoDB's primary mechanism for preventing phantom reads under repeatable read without full serializable isolation.
Code Example
Demonstrating InnoDB lock types with practical examples
-- Setup: orders table with an index on status
CREATE TABLE orders (
id INT PRIMARY KEY,
status VARCHAR(20),
total DECIMAL(10,2),
INDEX idx_status (status)
);
INSERT INTO orders VALUES (1,'PENDING',100),(5,'PENDING',200),(10,'DONE',50);
-- 1. ROW LOCK: locks the exact index record
-- Acquired by SELECT ... FOR UPDATE on a unique index hit
START TRANSACTION;
SELECT * FROM orders WHERE id = 5 FOR UPDATE;
-- Locks only the row with id=5. Other transactions can still
-- read/write id=1 or id=10 concurrently.
-- 2. GAP LOCK: locks the gap BETWEEN index values, prevents inserts
-- Acquired when searching a range on a non-unique index
START TRANSACTION;
SELECT * FROM orders WHERE status = 'PENDING' FOR UPDATE;
-- Locks the gap before the first PENDING row and after the last PENDING row.
-- Another transaction CANNOT insert a new PENDING order until this commits.
-- Gap locks are SHARED — two transactions can both hold gap locks on same gap.
-- 3. NEXT-KEY LOCK: row lock + gap lock before it (default InnoDB lock)
-- Used for range scans to prevent phantoms
START TRANSACTION;
SELECT * FROM orders WHERE id BETWEEN 3 AND 8 FOR UPDATE;
-- Acquires next-key lock on (id=5 row) + gap (1, 5] + gap (5, 10)
-- Prevents: insert of id=4, id=6, id=7, or id=8 by other transactions
-- DIAGNOSING DEADLOCKS in Spring Boot:
-- InnoDB rolls back the lighter transaction and throws:
-- com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException
-- (mapped to Spring's CannotAcquireLockException)
-- Check the latest deadlock details:
SHOW ENGINE INNODB STATUS;
-- Look for 'LATEST DETECTED DEADLOCK' section
-- Avoid deadlocks: always acquire locks in the same order across transactions
-- Use @Retryable in Spring to retry on CannotAcquireLockException
Common Mistakes & Pitfalls
This question differentiates candidates who understand why deadlocks happen and how to diagnose them from those who only know surface-level SQL.
Check your understanding
Answer these without looking back at the article.
- What is an intention lock in InnoDB and why does it exist?
- How does READ COMMITTED isolation level change which locks InnoDB acquires?
- How would you configure Spring Boot to automatically retry a transaction that failed due to a deadlock?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.