아래와 같이 4가지 Transaction Isolation Level이 존재한다.
- READ UNCOMMITTED
- READ COMMITTED
- REPEATED READ
- SERIALIZABLE
사전에 EMPLOYEE라는 테이블에 예시 데이터를 몇 개 넣고 시작하자!
READ UNCOMMITTED
다른 트랜잭션에서 커밋하지 않은 데이터들을 읽어올 수 있는 LEVEL
Transactio01에서 READ UNCOMMITTED를 걸었다.
그 와중에 또 다른 Transaction02에서 아래와 같이 UPDATE, INSERT 하는 Transaction을 생성하였다. (커밋 이전)
커밋을 하지 않았음에도 불구하고 Transactio01 해당 결과가 조회 가능하다.
이 결과 우리가 알 수 있는 것은 세 가지이다.
- 아직 COMMIT 하지 않은 신뢰 할 수 없는 데이터를 읽어온다. (dirty read)
- 한 트랜잭션에서 동일한 SELECT 쿼리의 결과가 다르다. (non-repeatable read)
- 이전에 없었던 SELECT 쿼리 결과에 없던 값이 생성된다. (phantom read)
READ COMMIT
예상할 수 있듯이 위와는 정 반대의 결과를 도출해낸다.
즉 COMMIT 한 정보만을 SELECT 할 수 있다.
(단순 반복 과정이니 자세한 과정은 생략하겠다.)
아직 COMMIT 하지 않은 신뢰 할 수 없는 데이터를 읽어온다. (dirty read)- 한 트랜잭션에서 동일한 SELECT 쿼리의 결과가 다르다. (non-repeatable read)
- 이전에 없었던 SELECT 쿼리 결과에 없던 값이 생성된다. (phantom read)
READ UNCOMMITTED와는 달리 dirty read 가 제외된다. (커밋을 무조건 해야 되니깐)
REPEATABLE READ
이건 좀 신기하다.
내가 쿼리를 테스트해보기 전에 기대한 결과는 non-repeatable read 까지만 제외될 것으로 생각하였다.
아직 COMMIT 하지 않은 신뢰 할 수 없는 데이터를 읽어온다. (dirty read)한 트랜잭션에서 동일한 SELECT 쿼리의 결과가 다르다. (non-repeatable read)- 이전에 없었던 SELECT 쿼리 결과에 없던 값이 생성된다. (phantom read)
[TRANSACTION 01] - REPEATABLE READ 시작
[TRANSACTION 02] - 커밋하지 않고 UPDATE / INSERT 실행
[TRANSACTION 01] - 조회
커밋되지 않은 정보는 조회되지 않음
(dirty read)
[TRANSACTION 02] - 커밋
[TRANSACTION 01] - 조회
한 트랜잭션에서 SELECT의 쿼리 결과가 동일 (non-repeatable read)
SELECT 쿼리의 결과에 없던 데이터가 생기지 않음 (phantom read)
결론
아직 COMMIT 하지 않은 신뢰 할 수 없는 데이터를 읽어온다. (dirty read)한 트랜잭션에서 동일한 SELECT 쿼리의 결과가 다르다. (non-repeatable read)이전에 없었던 SELECT 쿼리 결과에 없던 값이 생성된다. (phantom read)
어떻게 이와 같은 결과가 나타는 것일까?
SNAPSHOT의 차이이다.
즉 READ UNCOMMITTED 같은 경우에는 SELECT 쿼리로 데이터를 읽어 올 때 테이블에 LOCK을 걸지 않고 해당 시점의 SNAPSHOT을 구축하여 해당 시점에 대한 최신의 데이터를 불러온다.
반면에 REPEATABLE READ는 처음에 데이터를 일어올 때의 SNAPSHOT에서 모두 데이터를 불러온다.
- 그러기 때문에 SELECT를 하더라도 결과가 항상 처음과 동일했던 것이다. (phantom-read도 발생하지 않음)
SELIALIZABLE
동시성을 상당 부분 포기하고 안정성에 치중한 ISOLATION LEVEL
단순 SELECT를 하더라도 해당 쿼리를 SELECT... FOR SHARE로 변환한다.
[TRANSACTION 01]
[TRANSACTION 02]
SHARED LOCK이 걸려있으므로 조회는 가능하지만 만약 아래와 같이 UPDATE를 한다면
TRANSACTION 01에서 커밋하기까지를 끝까지 기다리지 않고 타임아웃을 발생시킴
결론
한 트랜잭션에서 SELECT를 실행하면 그 트랜잭션이 COMMIT 하기 이전까지 조회를 제외한 어떠한 작업도 할 수 없기 때문에
아직 COMMIT 하지 않은 신뢰 할 수 없는 데이터를 읽어온다. (dirty read)한 트랜잭션에서 동일한 SELECT 쿼리의 결과가 다르다. (non-repeatable read)이전에 없었던 SELECT 쿼리 결과에 없던 값이 생성된다. (phantom read)
세 가지 일은 발생할 일이 없다.
References
https://jupiny.com/2018/11/30/mysql-transaction-isolation-levels/
'CS > DataBase' 카테고리의 다른 글
(MySQL) MySQL 아키텍처 (0) | 2022.08.31 |
---|---|
(MySQL) MMM, MHA (0) | 2020.04.05 |
(MySQL) Replication (0) | 2020.03.29 |
(MySQL) Direct I/O (0) | 2020.03.08 |
(MySQL) Adaptive Hash Index (0) | 2020.03.08 |