
트랜잭션 아이솔레이션 레벨
https://bocho-developer.tistory.com/11
데이터베이스 트랜잭션 격리수준
트랜잭션이란? 그동안 트랜잭션에 많은 관심을 기울였고 한번 정리할때가 되어 글을 작성해 보는 시간이다. 우선 트랜잭션은 데이터베이스에서 하나의 기능을 수행하기 위한 작업의 단위이다.
bocho-developer.tistory.com
작년에 이부분에 대해 간단히 정리했고 부족한점들이 보였다.
이번 글은 Repeatable Read 에 대해 좀 중점적으로 정리한 글이다.
리피터블 리드 (Repeatable Read)
동일한 쿼리를 여러번 조회해도 같은 결과 값을 얻게 된다. 하지만, SERIALIZABLE과 다르게 행이 추가되는 것을 막지는 않는다. 이로 인해 팬텀 리드 현상이 발생할 수 있다.
팬텀 리드란? - 한 트랜잭션에서 같은 쿼리를 2번이상 조회했을 때 없던 결과가 조회되는 상황
예시)
1. A 트랜잭션이 값을 조회 후 아직 끝나지않음
2. B 트랜잭션이 값을 변경 후 커밋
3. A는 그 값을 다시 조회해도 트랜잭션 번호를 참고하여 자신보다 먼저 실행된 트랜잭션의 데이터만을 조회하기때문에 같은 값만을 조회
4. 조회할때는 스냅샷을 참고해서 조회한다.
MySQL의 기본레벨
- MySQL의 기본값은 리피터블 리드이다. 그러나 일반적으로 MySQL의 리피터블 리드에서는 팬텀리드가 발생하지 않는다.
- MySQL은 MVCC를 사용하여 팬텀 읽기를 방지하고 있기 때문이다.
MVCC(Multi-Version Concurrency Control)
- 트랜잭션 시작 될때 스냅샷을 생성하고 해당 스냅샷 기준으로 데이터를 읽는다.
- 스냅샷 - 변경전의 데이터값을 보관 , 즉 롤백할때 돌아갈 수 있는 데이터
- 트랜잭션 A가 SELECT * FROM users;를 실행중
- 트랜잭션 B가 INSERT, UPDATE, DELETE로 데이터를 수정해도
- 트랜잭션 A는 시작 시점의 데이터(스냅샷)를 계속 읽는다.
리피터블 리드는 같은 데이터를 계속 조회 / 팬텀리드는 다른행이 추가되어 조회값이 달라진다.
이 두개가 반대되는거 같아 잘 이해가 안갔다.
그러나 차이점이 있다.
Repeatable Read는 "읽은 데이터의 변경"을 막아주지만, "새로운 데이터의 추가"는 막지 않는다.
스냅샷이 가지고있는 데이터들의 SELECT, UPDATE, DELETE 쿼리 실행시 데이터 변경은 막아주지만 INSERT 쿼리로 추가된 행은 막지 못한다는 것이다.
트랜잭션 시작 시 생성된 스냅샷이 가지고 있는 데이터들의 수정은 불가능하다. 그리고 계속 기존의 데이터들의 값을 읽게 된다.
그러나 SELECT 쿼리를 실행할 때는 스냅샷 기반으로만 동작하는 것이 아니라 실제 데이터베이스에서도 데이터를 볼 수 있다.
즉, 스냅샷에 포함되지 않는 새로운 데이터가 현재 데이터베이스에 존재하므로 그 데이터는 SELECT 쿼리를 실행할 때 결과에 포함되는것이다.
또 하나 SELECT FOR UPDATE
-- Transaction 1
SELECT * FROM users WHERE age > 25; -- MVCC 스냅샷 읽음
-- id=1, name='John', age=30
-- id=2, name='Jane', age=28
-- Transaction 2
UPDATE users SET age = 27 WHERE id = 4; -- 기존에 id=4는 age가 20이었음
COMMIT;
-- Transaction 1
SELECT * FROM users WHERE age > 25; -- 여전히 스냅샷 데이터
-- id=1, name='John', age=30
-- id=2, name='Jane', age=28
SELECT * FROM users WHERE age > 25 FOR UPDATE; -- 실제 테이블 읽음
-- id=1, name='John', age=30
-- id=2, name='Jane', age=28
-- id=4, name='Bob', age=27
A사용자가 잠금없는 SELECT 문으로 데이터를 조회-> B가 update 후 커밋 -> A가 SELECT FOR UPDATE 잠금읽기로 조회 -> 잠금읽기 사용시 스냅샷(언두로그) 아닌 실제 테이블로부터 레코드를 조회하므로 Phantom Read가 발생할 수 있다.
- 첫 번째 SELECT: 일반 조회 (MVCC 사용)
- 두 번째 SELECT: FOR UPDATE (실제 테이블 조회)
- SELECT FOR UPDATE는 **락(lock)**을 사용하는 방식이므로, 스냅샷이 아니라 실시간 데이터를 기준으로 작동한다
'DB' 카테고리의 다른 글
| EXPLAIN 발표 (2) | 2025.02.01 |
|---|
