토픽 166 / 201·NewSQL 및 특수 목적 DB
Phantom Read 해결
Phantom Read 해결
트랜잭션 내에서 동일한 범위 쿼리를 반복 실행할 때 다른 트랜잭션의 INSERT로 인해 새로운 행이 나타나는 현상(Phantom Read)과 이를 방지하기 위한 격리 수준 및 잠금 기법
목적: 트랜잭션 격리, 데이터 일관성, 반복 가능한 읽기 보장
Phantom Read 발생 조건
- •Repeatable Read 이하 격리 수준
- •범위 쿼리 (WHERE age > 20)
- •다른 트랜잭션의 INSERT/DELETE
해결 방법
- •Serializable 격리 수준: 가장 엄격, 범위 잠금, 성능 저하
- •Gap Lock (MySQL InnoDB): 인덱스 레코드 사이의 갭을 잠금, INSERT 차단
- •Next-Key Lock (MySQL): Record Lock + Gap Lock 조합
- •Predicate Lock: 조건(Predicate)에 대한 잠금, 범위 전체 보호
- •MVCC + Snapshot: PostgreSQL 방식, 스냅샷 기반 일관된 읽기
Gap Lock 상세
- •레코드 사이의 빈 공간(Gap)을 잠금
- •예: age 인덱스에서 (20, 30) 갭 잠금 → 21~29 INSERT 차단
- •Repeatable Read에서 자동 적용 (MySQL InnoDB)
DBMS별 처리
- •MySQL InnoDB: Repeatable Read + Gap Lock으로 Phantom 방지
- •PostgreSQL: Repeatable Read에서 Snapshot Isolation(SI) 사용, Serializable에서 SSI 사용
- •Oracle: Serializable 또는 SELECT FOR UPDATE
- •SQL Server: Serializable 또는 HOLDLOCK 힌트
장점: 데이터 일관성 보장, 예측 가능한 결과
단점: 동시성 저하, 잠금 경합, 데드락 가능성
적용사례: 재고 관리, 금융 거래, 보고서 생성, 집계 연산
기술요소: Gap Lock, Next-Key Lock, Predicate Lock, Serializable, MVCC
비교: Dirty Read(커밋 전 읽기) vs Non-Repeatable Read(값 변경) vs Phantom Read(행 추가/삭제)
연관: 트랜잭션 격리 수준, MVCC, 잠금, Serializable, InnoDB