팬텀 충돌
설명 영상 팬텀 충돌 · 2:38
왜 배우는가: 팬텀충돌은 행 단위 잠금만으로는 막을 수 없는 대표적인 동시성 이상 현상이다. 예약·재고처럼 조건 조회 후 삽입하는 업무에서 실제 무결성 사고로 이어지므로 실무에서 중요하다. 격리 수준 비교와 동시성 제어 기법 비교 문제에서 반복해 출제되는 개념이다.
출제 이력: 제135회 1교시 11번, 제98회 1교시 3번
1. 한 줄 정의와 핵심 키워드
팬텀충돌은 한 트랜잭션이 조건에 맞는 새 레코드를 삽입·삭제해 다른 트랜잭션의 범위 질의 결과가 달라지는 동시성 충돌이다.
핵심 키워드는 다음과 같다.
- 팬텀(Phantom): 검색 조건에 새로 나타나거나 사라지는 레코드다.
- 범위 질의: 조건(WHERE 절)으로 여러 행을 조회하는 질의다.
- 삽입·삭제 충돌: 기존 행을 바꾸지 않고 행 집합 자체를 바꾸는 쓰기다.
- 팬텀 리드(Phantom Read): 같은 조건을 두 번 조회했을 때 결과 행 집합이 달라지는 읽기 이상 현상이다.
- 술어 잠금(Predicate Lock): 데이터 값이 아니라 검색 조건을 잠가 그 조건에 해당하는 삽입을 막는 방식이다.
- 넥스트 키 락(Next-Key Lock): 데이터베이스 잠금 방식의 하나다.
- 직렬 가능성(Serializability): 동시 실행 결과가 어떤 직렬 실행 결과와 같음을 보장하는 성질이다.
- 충돌 구체화(Materializing the Conflict): 잠글 대상이 없는 팬텀을 실제 잠금 객체로 바꾸는 우회 기법이다.
2. 개념 풀이
쉬운 말로 설명하면, 어떤 조건으로 조회했더니 10건이 나왔다. 다른 트랜잭션이 같은 조건에 해당하는 1건을 넣고 커밋하면, 다시 조회할 때 11건이 된다. 이때 새로 나타난 1건이 유령(팬텀)이다. 정식 정의는 한 트랜잭션의 쓰기가 다른 트랜잭션의 검색 질의 결과를 바꾸는 현상이다. 기존 행 하나를 두고 다투는 것이 아니므로 충돌의 본질이 행 단위가 아니라 조건(범위) 단위에 있다.
팬텀이 어려운 이유는 잠글 대상이 없다는 데 있다. 질의 결과가 0건이면 잠글 행이 존재하지 않아 행 잠금을 걸 수 없다. 그래서 두 트랜잭션이 모두 빈 결과를 확인하고 각자 삽입해 제약 조건을 위반할 수 있다.
팬텀 리드는 같은 트랜잭션 안에서 같은 조건의 질의를 반복했을 때 행 집합이 바뀌는 읽기 이상 현상이다. 팬텀충돌은 이 현상을 일으키는 원인 쪽 개념이다.
술어 잠금은 검색 조건 자체를 잠가 그 조건에 맞는 새 행의 삽입을 차단한다. 이론적으로는 가장 정확하지만 구현 비용이 커서 DBMS에서는 근사 방식으로 구현되는 경우가 많다.
넥스트 키 락은 데이터베이스 잠금 방식의 하나다. 술어 잠금을 인덱스 구조로 근사한 방식이다. 넥스트 키 락의 사용 여부는 DBMS별로 확인한다.
쓰기 스큐는 두 트랜잭션이 같은 객체 집합을 읽고 서로 다른 객체를 갱신해 제약 조건을 깨뜨리는 현상이다. 팬텀은 쓰기 스큐를 유발하는 대표 원인으로 설명된다.
3. 등장 배경과 필요성
DBMS는 다수 사용자가 트랜잭션을 동시에 실행하도록 설계된다. 이때 결과는 어떤 직렬 실행과 같아야 하며, 이것이 직렬성의 요구다. 행 단위 잠금과 2단계 잠금(2PL)은 이미 존재하는 행 사이의 충돌을 막는 데 효과적이다. 그러나 조건 조회 뒤 삽입하는 패턴은 기존 행 잠금으로 막을 수 없다.
가상의 예로 회의실 예약을 들 수 있다. 두 사용자가 같은 시간대의 예약 건수를 각각 0건으로 확인하고 동시에 예약을 삽입하면 중복 예약이 생긴다. 이 문제는 두 트랜잭션이 같은 행을 건드리지 않아 발생하므로 팬텀충돌의 전형이다.
동시성 제어 기법이 발전하면서 격리 수준이 표준화되었다. SQL 표준의 격리 수준은 허용하는 이상 현상의 종류로 구분된다. 팬텀 리드는 격리 수준 비교의 핵심 기준이 되었다.
스냅숏 격리가 널리 쓰이면서 팬텀 문제가 다시 주목받았다. 스냅숏 격리는 대부분의 동시성 이상을 막지만 직렬화 가능성을 완전히 보장하지 않는다. 그래서 쓰기 스큐와 팬텀 같은 현상을 막기 위한 추가 기법이 필요하다.
따라서 팬텀충돌은 격리 수준 선택, 잠금 설계, 데이터 모델링 세 방향에서 해결을 고민해야 하는 개념이다. 시험에서는 이 세 방향을 비교하는 형태로 자주 출제된다.
4. 구성요소·원리·절차
팬텀충돌은 세 가지 요소로 구성된다. 검색 조건, 그 조건이 만든 결과 집합, 그리고 조건에 맞는 새 레코드를 만드는 트랜잭션이다. 핵심은 범위 조건이다. 이미 존재하는 행의 잠금만으로는 아직 없는 행을 막을 수 없다.
| 구성요소 | 역할 | 비고 |
|---|---|---|
| 검색 조건(술어, Predicate) | 읽을 범위를 정한다 | 예: 특정 시간대 예약 |
| 범위 결과 집합 | 질의가 읽은 레코드 묶음 | 삽입이나 삭제로 바뀜 |
| 변경 트랜잭션 | 조건에 맞는 행을 만들거나 지움 | 기존 행 잠금과 무관 |
설명: 구성요소 중 조건과 결과 집합은 질의 시점에 정해진다. 변경 트랜잭션은 그 뒤에 조건을 만족하는 새 행을 넣는다. 두 트랜잭션이 같은 행을 건드리지 않아도 결과가 달라진다는 점이 팬텀충돌의 특징이다.
팬텀충돌은 존재하지 않던 행의 삽입으로 범위 질의 결과가 바뀌는 충돌이다.
원리는 다음과 같다. 데이터 항목 잠금은 이미 존재하는 행에만 걸린다. 새로 삽입되는 행은 잠금 대상이 아니다. 따라서 T1의 범위 질의 결과에 T2가 넣은 행이 나중에 나타난다. 직렬 실행에서는 이런 결과가 나올 수 없으므로 직렬 가능성이 깨진다.
절차는 다음 순서로 진행된다.
- T1이 조건 P로 범위 질의를 실행해 결과 집합을 얻는다.
- T2가 조건 P를 만족하는 새 레코드를 삽입하고 커밋한다.
- T1이 같은 질의를 다시 실행하면 행 수가 달라진다. 이것이 팬텀 리드다.
- 두 트랜잭션을 직렬로 실행한 결과와 다르므로 직렬 가능성 위반이다.
이를 기호로 쓰면 다음과 같다. $r_1(P) \rightarrow w_2(x \in P) \rightarrow r_1(P)$ 여기서 r_1(P)는 T1이 조건 P로 읽는 연산, w_2(x \in P)는 T2가 P를 만족하는 행 x를 쓰는 연산이다. 두 번째 r_1(P)의 결과가 첫 번째와 다르면 팬텀이다.
이 흐름에서 팬텀 리드는 재질의 결과가 달라진 시점을 가리킨다. 답안에는 삽입 단계를 빠뜨리지 않아야 한다.
5. 관련 법령·기준·표준
팬텀충돌은 국내 법령이 정한 개념이 아니다. 데이터베이스 격리 수준 표준에서 나온 현상이다. ANSI SQL-92가 격리 수준을 정의하면서 Dirty Read, Non-repeatable Read, Phantom Read 세 가지 현상으로 기준을 세웠다. 이후 SQL 표준 개정에서도 같은 틀이 유지되었다. 아래 표는 격리 수준별 허용 여부다.
| 격리 수준 | Dirty Read | Non-repeatable Read | Phantom Read |
|---|---|---|---|
| READ UNCOMMITTED | 허용 | 허용 | 허용 |
| READ COMMITTED | 방지 | 허용 | 허용 |
| REPEATABLE READ | 방지 | 방지 | — |
| SERIALIZABLE | 방지 | 방지 | — |
표에서 읽을 점은 격리 수준별로 팬텀 리드의 허용 여부를 비교한다는 것이다. 팬텀 방지 여부는 격리 수준과 DBMS의 구현을 함께 고려해야 한다.
팬텀을 막는 기법은 표준 용어가 아니라 DBMS 구현 기법이다. 대표 기법은 다음과 같다.
| 기법 | 원리 | 적용 예 |
|---|---|---|
| 프레디킷 락(Predicate Lock) | 조건 P 전체에 잠금을 건다 | 이론적 기준, 구현은 제한적 |
| 넥스트 키 락(Next-Key Lock) | 데이터베이스 잠금 방식이다 | 적용 방식은 DBMS별로 확인 |
| 직렬성 스냅숏 격리(SSI) | 충돌 의존 관계를 추적해 위험 트랜잭션을 중단한다 | PostgreSQL 방식 |
| 충돌 구체화 | 범위 조합 행을 미리 만들어 행 잠금으로 바꾼다 | 회의실 예약, 다음 6개월 분 행 생성 |
이어지는 내용
- 6. 유형과 비교
- 7. 장단점·한계와 개선 방향
- 8. 사례 또는 계산 예제
- 9. 최근 동향과 쟁점
- 10. 흔한 실수와 채점 포인트
- 11. 암기 정리
- 12. 답안 구성 예시
- 13. 예상 변형 문항
로그인하면 하루 2페이지까지 무료로 전체를 읽을 수 있습니다.
앱에서 이 단원 읽기