Blog
Anki
데이터베이스 문제
20251219 데이터베이스 문제

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만
INSERTRecord 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');