데이터베이스

팬텀 충돌(Phantom Conflict)

팬텀 충돌(Phantom Conflict, 팬텀 문제, Phantom Read)트랜잭션이 동일한 조건으로 여러 번 조회할 때, 다른 트랜잭션이 중간에 데이터를 삽입하거나 삭제하여 결과가 달라지는 현상을 의미합니다.
이는 반복 가능한 읽기(Repeatable Read) 수준에서도 발생할 수 있는 문제이며, Serializable(직렬화) 수준의 격리성을 적용해야 방지할 수 있습니다.

※ 팬텀 충돌의 내용은 DB를 배운 사람이면 모두 알 수 있는 내용일 텐데 용어가 생소하신 분들이 있을 것 같아 정리해봤습니다. 참고로 정보관리기술사 135회 1교시에 “팬텀 충돌”에 대해 설명하라는 문제가 출제되어 Topic을 따로 정리해봤습니다.

1. 팬텀 충돌(Phantom Read) 예제

📌 예제 상황:

  • 트랜잭션 Asalary > 5000인 직원을 조회하고 있음
  • 트랜잭션 Bsalary = 6000인 새 직원을 추가하면, 트랜잭션 A가 다시 같은 조건을 조회할 때 결과가 달라짐

Step 1: 트랜잭션 A가 첫 번째 조회 수행

-- 트랜잭션 A (급여 5000 초과 직원 조회)
BEGIN TRANSACTION;
SELECT * FROM employees WHERE salary > 5000;

결과:

emp_idnamesalary
101Alice6000
102Bob7000

Step 2: 트랜잭션 B가 새로운 직원 추가

-- 트랜잭션 B (새로운 직원 추가)
INSERT INTO employees (emp_id, name, salary) VALUES (103, 'Charlie', 6500);
COMMIT;

Step 3: 트랜잭션 A가 같은 조건으로 다시 조회

SELECT * FROM employees WHERE salary > 5000;

변경된 결과:

emp_idnamesalary
101Alice6000
102Bob7000
103Charlie6500

🚨 문제 발생:
트랜잭션 A가 같은 조건으로 다시 조회했지만, 이전과 다른 결과가 반환됨팬텀 충돌(Phantom Read) 발생

2. 팬텀 충돌이 발생하는 이유

  • 트랜잭션 Asalary > 5000 조건을 만족하는 데이터를 조회
  • 트랜잭션 Bsalary = 6500인 새로운 행을 추가
  • 트랜잭션 A가 다시 조회할 때 처음과 다른 데이터가 존재

이러한 문제는 기존 데이터를 수정(Update)하는 경우가 아니라, 새로운 데이터가 추가(Insert) 또는 삭제(Delete)될 때 발생합니다.

3. 팬텀 충돌 방지 방법

(1) 높은 수준의 트랜잭션 격리 사용 (Serializable)

팬텀 충돌은 Repeatable Read(반복 가능한 읽기) 수준에서도 방지되지 않으며, Serializable(직렬화) 격리 수준에서만 해결됩니다.

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
SELECT * FROM employees WHERE salary > 5000;

Serializable 격리 수준을 사용하면 트랜잭션이 완료될 때까지 다른 트랜잭션이 새로운 데이터를 삽입하지 못하게 함
성능 저하 위험이 있음 (Lock이 많이 발생함)

(2) 공유 락(Shared Lock) 사용

팬텀 충돌을 방지하려면 테이블에 공유 락(Shared Lock)을 걸어, 다른 트랜잭션이 INSERT, DELETE를 수행하지 못하게 할 수도 있음.

SELECT * FROM employees WHERE salary > 5000 FOR UPDATE;

FOR UPDATE를 사용하면 해당 행이 잠겨, 다른 트랜잭션이 INSERT/DELETE를 하지 못하게 됨.
단점: 신규 행을 추가하는 것은 막지 못함 → Serializable 수준이 필요할 수 있음.

(3) 갭 락(Gap Lock) 활용 (InnoDB)

MySQL/InnoDB에서는 Gap Lock을 사용하여 팬텀 문제를 방지할 수 있음.

SELECT * FROM employees WHERE salary > 5000 LOCK IN SHARE MODE;

범위 내에서 새로운 행 추가 방지 (팬텀 Read 차단 가능)
일부 DBMS에서만 지원됨 (MySQL InnoDB에서 사용 가능)

4. 팬텀 충돌 vs 기타 트랜잭션 충돌 비교

유형설명예제해결 방법
Dirty Read (더티 리드)커밋되지 않은 데이터를 다른 트랜잭션에서 읽음한 트랜잭션에서 UPDATE 후, 다른 트랜잭션이 변경된 데이터를 읽을 수 있음READ COMMITTED 이상 격리 수준 사용
Non-Repeatable Read (비반복 읽기)동일한 데이터를 여러 번 조회할 때, 값이 변경됨한 트랜잭션에서 조회 후, 다른 트랜잭션이 UPDATE하면 조회 결과가 다름REPEATABLE READ 이상 격리 수준 사용
Phantom Read (팬텀 충돌)동일한 조건으로 조회했을 때, 행이 추가/삭제되어 결과가 달라짐첫 번째 조회 후, 다른 트랜잭션이 INSERT/DELETE하면 다시 조회할 때 결과가 다름SERIALIZABLE 격리 수준 사용

5. 결론

📌 팬텀 충돌(Phantom Conflict, Phantom Read)이란?

  • 동일한 SELECT 쿼리를 여러 번 실행했을 때, 다른 트랜잭션이 데이터를 추가하거나 삭제하여 결과가 달라지는 문제
  • 일반적으로 INSERT 또는 DELETE로 인해 발생 (UPDATE는 영향 없음)

📌 어떻게 해결할까?

  • Serializable 격리 수준 사용 (SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;)
  • SELECT … FOR UPDATE 또는 공유 락 (LOCK IN SHARE MODE) 적용
  • MySQL의 경우 Gap Lock 활용

🚀 트랜잭션 처리에서 팬텀 충돌을 방지하려면, 트랜잭션 격리 수준을 높이고 적절한 Lock을 활용해야 합니다!

zerg96

Recent Posts

요양원 선택 전 반드시 확인해야 할 것들, 부모님 맡기기 전에 보세요

요양원 선택 전 반드시 확인해야 할 체크리스트를 공개합니다. 공식 평가 자료 조회법, 방문 시 확인…

3일 ago

공공기관 채용 비리, 내부에서 터져나온 충격 증언

공공기관 채용 비리의 실태와 피해 지원자의 대응법을 정리했습니다. 채용 비리 신고 방법, 공익신고자 보호제도, 취준생…

3일 ago

주식 손실 났을 때 세금 줄이는 방법, 아는 사람만 씁니다

주식 손실을 세금 절약에 활용하는 합법적 방법을 공개합니다. 해외주식 손익통산, ISA 계좌 활용, 연금계좌 절세까지…

3일 ago

음식 배달 늦으면 소비자가 취소할 수 있다, 몰랐던 권리

배달이 예상 시간보다 크게 늦으면 취소·환불을 요청할 수 있습니다. 배달앱별 지연 취소 방법과 잘못 배달됐을…

3일 ago

휴대폰 요금제 바꾸면 연 수십만원 절약, 지금 내 요금제 확인하세요

통신비 절약의 핵심은 요금제 최적화입니다. 내 데이터 사용량 확인법, 알뜰폰 전환 비교, 위약금 없이 요금제…

3일 ago

퇴직금 못 받았다면, 지금 당장 이렇게 하세요

퇴직 후 퇴직금을 받지 못했다면 즉시 노동부에 신고하세요. 지급 기한, 자격 요건, 신고 방법, 소액체당금…

3일 ago