문제
표준 SQL 격리 수준 기준에서, 다음 상황에서 트랜잭션 T1과 T2가 동시에 실행될 때 SERIALIZABLE 격리 수준에서는 방지되지만 REPEATABLE READ 격리 수준에서는 발생할 수 있는 이상 현상의 이름과 이 현상이 발생하는 구체적인 시나리오를 설명하시오.
[상황]
- T1: SELECT COUNT(*) FROM orders WHERE status = 'PENDING'
- T2: INSERT INTO orders VALUES (101, 'PENDING')
- T1: SELECT COUNT(*) FROM orders WHERE status = 'PENDING' (재실행)
정답
Phantom Read 현상이다. REPEATABLE READ 격리 수준에서는 기존 레코드에 대한 반복 조회의 일관성은 보장하지만, 범위 조건에 새롭게 삽입되는 레코드까지 항상 차단하지는 못한다. 따라서 T1이 첫 번째 SELECT로 PENDING 주문 수를 조회한 뒤 T2가 새로운 PENDING 주문을 삽입하고 커밋하면, T1이 동일한 조건으로 다시 조회할 때 결과 집합의 행 수가 달라져 새로운 행이 나타난 것처럼 보일 수 있다. SERIALIZABLE은 이러한 범위 조회까지 직렬화하여 Phantom Read를 방지한다.
Phantom Read팬텀 리드유령 읽기새로운 레코드삽입범위 검색
해설
Phantom Read는 같은 트랜잭션 안에서 동일한 검색 조건으로 다시 조회했을 때, 다른 트랜잭션의 INSERT 또는 DELETE로 인해 결과 집합의 행 수가 달라지는 현상이다. 표준 SQL 이론상 REPEATABLE READ는 기존 행의 반복 읽기 일관성은 보장하지만 범위 조건에 대한 새로운 행의 출현까지 모두 막는 것은 아니며, SERIALIZABLE은 이를 방지한다.