MySQL에서는 트랜잭션마다 트랜잭션 ID를 부여하여 트랜잭션 ID보다 작은 트랜잭션 번호에서 변경한 것만 읽게 된다.
아래에서 할 예시들은 트랜잭션 번호를 생략해두고 진행했다.
Repeatable Read에서는 다른 트랜잭션 격리수준인Read Uncommitted나Read Committed에서와 달리Non-Repeatable Read현상이 발생하지 않는다.
Non-Repeatable Read : 하나의 트랜잭션에서 같은 값을 두 번 select 했을 때 각각 다른 값이 읽히는 현상
이게 무슨 소리냐면
위 순서대로 진행이 된다면 데이터가 변경돼 Non-Repeatable Read 발생한다는 것이다.
그럼 문득 "하나의 트랜잭션에서 같은 데이터의 조회를 2번 할 일이 없다면?" 이라고 생각이 들 수도 있다.
MySQL InnoDB 스토리지 엔진의 기본 트랜잭션 격리수준으로
Repeatable Read을 설정한 이유가 뭘까?

위 사진은 MySQL docs에서 Repeatable Read를 정의한 내용으로
첫 줄의 "Consistent reads within the same transaction read the snapshot established by the first read."
= 동일한 트랜잭션 내에서의 일관된 조회는 첫 번째 조회에 의해 설정된 스냅샷을 읽는다. 는 뜻이다.

스냅샷 : "일관된 조회를 위해 특정 격리 수준에서 사용되는 것으로서 다른 트랜잭션에 의해 변경 사항이 커밋되더라도 동일하게 유지되는 특정 시간의 데이터 표현"
이번엔 다른 형태의 트랜잭션을 가정을 들어 설명하겠다.
위 과정을 겪으면 어떻게 될까?
정답은 바로 1번이다. 말이 길어져서 간단히 그림으로 설명하면

이렇게 plan을 C 중간에 수정하고 커밋하더라도 before이었던 레코드가 그대로 출력된다는 뜻이다.
트랜잭션 격리수준이 Repeatable Read 라면 한 트랜잭션 내에서 동일한 select 를 2번 이상 시도해도 동일한 결과가 반환된다.
다른 테이블 데이터 역시 최초 조회(first read) 시점에서의 데이터가 마치 스냅샷(snapshot)처럼 유지되어 있던 것이다.

그렇게 할 수 있는 이유는
일관된 조회 : 조회한 시점을 기준으로 쿼리 결과를 표시하는 스냅샷 정보를 사용하는 것
2번째 줄의 If queried ~ 로 시작하는 문구를 보면 "조회된 데이터(queried data)가 다른 트랜잭션에 의해 변경되었다면 본래 데이터는 undo log 의 내용을 통해 재구성된다." 라는 뜻인데
트랜잭션 C는 D가 수정한 데이터의 원본 데이터가 undo log 에 들어갔고 이 undo log 로부터 해당 데이터를 가져왔다는 것을 알 수 있다.
언두 로그 : 활성 트랜잭션에 의해 수정된 데이터의 복사본을 보관하는 저장 영역
즉, 수정하기 전 원본 데이터가 저장되는 영역
대신 Phantom Read 라고 하는 현상이 발생하기도 한다.
Phantom Read : 한 트랜잭션 내에서 동일한 쿼리를 보냈을 때 해당 조회 결과가 다른 경우
- Phantom Read와 Non-Repeatable Read의 차이??
- Non-Repeatable Read는 1개의 Row의 데이터의 값이 변경되는 것이며 (Update 또는 Delete)
- Phantom Read는 다수의 건을 요청하는 것에 대해서 데이터의 값이 변경되는 것
즉, Non-Repeatable Read는 위에서 봤다시피 1개의 Row의 데이터를 2번 조회하는 트랜잭션 내에서 다른 트랜잭션에 의해 update나 delete로 하나의 데이터가 변경됐을 때 언두 로그로 인해 변경되기 전의 데이터를 조회할 수 있다는 것이다.
Phantom Read를 예를 들어 설명하면
select * from member
E는 위와 같은 쿼리문이 2번 사용되는 트랜잭션이라고 생각하면 된다.
INSERT INTO member (member_id, member_name)
VALUES (70, 'Jehun')
commit
Phantom Read가 발생하는 것이다.기존에 Real MySQL 8.0 책을 정리했을 때 언두 로그를 활용한 Repeatable Read에 대해서 잘 몰랐는데 이제 어느 정도 이해가 된 것 같다.