MySQL InnoDB에서 PK/Unique Index 사용 시 Next-Key Lock이 걸리지 않는 조건은?
꼬리 질문
- Unique Index로 범위 검색(>, <, BETWEEN) 시에도 Record Lock만 걸리는가?
- 존재하지 않는 PK 값을 검색할 때 어떤 Lock이 걸리는가?
- Secondary Index와 Primary Key의 잠금 동작 차이는?
답변 보기
- 핵심 포인트 💡:
- Unique Index + Unique Search Condition(= 조건)일 때만 Record Lock만 사용
- 범위 검색(>, <, BETWEEN)은 Unique Index라도 Next-Key Lock 사용
- 존재하지 않는 값 검색 시 Gap Lock 발생 가능
- ✅ Record Lock만 걸리는 경우
SELECT * FROM t WHERE id = 5 FOR UPDATE;(PK로 정확히 하나의 행 검색)UPDATE t SET col = 1 WHERE id = 5;(Unique Index + = 조건)DELETE FROM t WHERE id = 5;(Unique Index + = 조건)
- ❌ Next-Key Lock이 걸리는 경우 (Unique Index라도)
SELECT * FROM t WHERE id > 5 FOR UPDATE;(범위 검색)UPDATE t SET col = 1 WHERE id BETWEEN 1 AND 10;(범위 검색)SELECT * FROM t WHERE id = 999 FOR UPDATE;(존재하지 않는 값 → Gap Lock)
- 출처
위 출처에서 "For a unique index with a unique search condition, InnoDB locks only the index record found, not the gap before it." 라고 명시되어 있음.
위 출처에서 "However, only an index record lock is required for statements that lock rows using a unique index to search for a unique row." 라고 명시되어 있음.
REPEATABLE READ에서 INSERT 시 Next-Key Lock이 걸리는가?
꼬리 질문
- INSERT와 UPDATE/DELETE의 잠금 방식 차이는?
- Insert Intention Gap Lock이란 무엇인가?
- INSERT 시 Duplicate Key가 발생하면 어떤 Lock이 걸리는가?
답변 보기
- 핵심 포인트 💡:
- INSERT는 Record Lock만 설정 (Next-Key Lock ❌)
- UPDATE/DELETE는 기본적으로 Next-Key Lock 사용
- INSERT 전에 Insert Intention Gap Lock이 설정됨 (다른 트랜잭션 삽입과 충돌 안 함)
- ✅ 정확한 잠금 동작
| 구문 | REPEATABLE READ 잠금 유형 |
|---|---|
| UPDATE (일반) | Next-Key Lock |
| DELETE (일반) | Next-Key Lock |
| UPDATE/DELETE (Unique + =) | Record Lock만 |
| INSERT | Record Lock만 |
- INSERT의 잠금 과정
- 1단계: Insert Intention Gap Lock 설정 (삽입 위치의 Gap에 대한 의도 표시)
- 2단계: 행 삽입 후 Exclusive Record Lock 설정
- Gap Lock이 아니므로 같은 Gap에 여러 트랜잭션이 동시 삽입 가능
- ❌ 흔한 오해
- "REPEATABLE READ에서 INSERT도 Next-Key Lock을 건다" → 틀림
- INSERT는 Gap Lock을 걸지 않아 동시성이 높음
- 코드 예시
-- 두 트랜잭션이 같은 Gap에 삽입 가능 (blocking 안 됨)
-- Transaction A
INSERT INTO t VALUES (5, 'A');
-- Transaction B (동시 실행 가능)
INSERT INTO t VALUES (6, 'B');- 출처
위 출처에서 "INSERT sets an exclusive lock on the inserted row. This lock is an index-record lock, not a next-key lock (that is, there is no gap lock)" 라고 명시되어 있음.
위 출처에서 "Prior to inserting the row, a type of gap lock called an insert intention gap lock is set." 라고 명시되어 있음.