공통 장면
같은 범위 100 ~ 200를 다시 읽을 때, InnoDB는 읽기 종류에 따라 고정하는 대상을 다르게 잡습니다.
핵심 차이는 팬텀 행을 처리하는 방식입니다. 일반 읽기는 결과를 스냅샷에 묶고, 잠금 읽기는 인덱스 범위를 잠가 새 행이 끼어들지 못하게 만듭니다.
SELECT * FROM 주문
WHERE 금액 BETWEEN 100 AND 200;
비교 질문
Consistent Read
일반 SELECT MVCC가 트랜잭션 시작 시점의 스냅샷을 유지
Locking Read
FOR UPDATE / FOR SHARE Gap Lock, Next-Key Lock으로 범위 자체를 보호
무엇이 고정되나
읽는 시점의 버전 현재 DB가 바뀌어도 T1은 같은 스냅샷을 계속 봅니다.
인덱스 범위와 그 사이의 갭 (100, 200) 구간에 새 레코드가 들어오지 못하게 잠급니다.
동시 INSERT 150
실제 DB에는 커밋될 수 있음 T2가 150을 넣어도, T1의 조회 결과에는 아직 반영되지 않습니다.
대기하거나 차단됨 150이 잠긴 범위 안이므로 락이 풀릴 때까지 끼어들 수 없습니다.
같은 범위 재조회
T1은 여전히 120, 180만 봄 팬텀 행은 생겼지만, 현재 트랜잭션의 읽기 결과에는 보이지 않습니다.
결과가 바뀔 여지를 줄임 범위 안 새 행이 생성되지 못하므로 재조회에서도 팬텀이 나타나지 않습니다.
팬텀 방지 방식
보이지 않게 막음 MVCC가 읽는 시점을 고정해 결과를 안정적으로 유지합니다.
못 들어오게 막음 락이 범위를 고정해 동시 INSERT 자체를 늦추거나 막습니다.