핵심 차이

같은 트랜잭션 안에서도 두 번째 SELECT 결과가 달라지는 이유는 ReadView 생성 시점입니다. READ COMMITTED는 조회할 때마다 새 스냅샷을 잡고, REPEATABLE READ는 첫 SELECT의 스냅샷을 계속 씁니다.

공통 타임라인
두 격리 수준 모두 같은 순서로 일이 일어나지만, 스냅샷을 잡는 순간이 다릅니다.
1단계
첫 번째 SELECT
트랜잭션이 처음으로 읽기를 수행합니다.
2단계
다른 트랜잭션 COMMIT
예시 행 값이 100 → 200으로 확정됩니다.
3단계
두 번째 SELECT
새 커밋을 같은 트랜잭션 안에서 다시 읽습니다.
READ COMMITTED

SELECT마다 새 ReadView
조회 단위로 최신 커밋을 다시 반영합니다.

ReadView #1 생성
처음 값 100을 읽음

첫 SELECT 시점의 활성 트랜잭션 목록으로 스냅샷을 만듭니다.

다른 트랜잭션이 COMMIT
현재 버전은 200으로 바뀜

다음 SELECT에서는 이 커밋이 새 기준선에 포함될 수 있습니다.

ReadView #2 새로 생성
두 번째 SELECT는 200을 봄

이전 스냅샷을 버리고 다시 캡처하므로, 방금 커밋된 변경이 바로 보입니다.

REPEATABLE READ

첫 SELECT의 ReadView 유지
트랜잭션 동안 같은 스냅샷을 계속 사용합니다.

ReadView #1 생성
처음 값 100을 읽음

첫 SELECT에서 만든 스냅샷이 이후 조회의 기준점이 됩니다.

다른 트랜잭션이 COMMIT
실제 현재 버전은 200

하지만 이 커밋은 이미 만들어 둔 스냅샷 바깥에서 일어난 변화입니다.

기존 ReadView #1 재사용
두 번째 SELECT도 100 유지

같은 ReadView로 판단하므로, 트랜잭션이 끝날 때까지 일관된 스냅샷을 봅니다.

정리: READ COMMITTED쿼리 단위 스냅샷, REPEATABLE READ트랜잭션 단위 스냅샷으로 생각하면 두 번째 SELECT 결과 차이가 바로 연결됩니다.