본문 바로가기

CS/DataBase

(MySQL) Transaction Isolation Levels

 

아래와 같이 4가지 Transaction Isolation Level이 존재한다.

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATED READ
  • SERIALIZABLE

사전에 EMPLOYEE라는 테이블에 예시 데이터를 몇 개 넣고 시작하자!

 


READ UNCOMMITTED

다른 트랜잭션에서 커밋하지 않은 데이터들을 읽어올 수 있는 LEVEL

 

Transactio01에서 READ UNCOMMITTED를 걸었다.

 

 

그 와중에 또 다른 Transaction02에서 아래와 같이 UPDATE, INSERT 하는 Transaction을 생성하였다. (커밋 이전)

 

커밋을 하지 않았음에도 불구하고 Transactio01 해당 결과가 조회 가능하다.

실행결과

이 결과 우리가 알 수 있는 것은 세 가지이다.

 

  1. 아직 COMMIT 하지 않은 신뢰 할 수 없는 데이터를 읽어온다. (dirty read)
  2. 한 트랜잭션에서 동일한 SELECT 쿼리의 결과가 다르다. (non-repeatable read)
  3. 이전에 없었던 SELECT 쿼리 결과에 없던 값이 생성된다. (phantom read)

READ COMMIT 

예상할 수 있듯이  위와는 정 반대의 결과를 도출해낸다.

즉 COMMIT 한 정보만을 SELECT 할 수 있다.

(단순 반복 과정이니 자세한 과정은 생략하겠다.)

 

  1. 아직 COMMIT 하지 않은 신뢰 할 수 없는 데이터를 읽어온다. (dirty read)
  2. 한 트랜잭션에서 동일한 SELECT 쿼리의 결과가 다르다. (non-repeatable read)
  3. 이전에 없었던 SELECT 쿼리 결과에 없던 값이 생성된다. (phantom read)

READ UNCOMMITTED와는 달리 dirty read 가 제외된다. (커밋을 무조건 해야 되니깐)


REPEATABLE READ

이건 좀 신기하다.

내가 쿼리를 테스트해보기 전에 기대한 결과는 non-repeatable read 까지만 제외될 것으로 생각하였다.

  1. 아직 COMMIT 하지 않은 신뢰 할 수 없는 데이터를 읽어온다. (dirty read)
  2. 한 트랜잭션에서 동일한 SELECT 쿼리의 결과가 다르다. (non-repeatable read)
  3. 이전에 없었던 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)

 

 

 

결론

  1. 아직 COMMIT 하지 않은 신뢰 할 수 없는 데이터를 읽어온다. (dirty read)
  2. 한 트랜잭션에서 동일한 SELECT 쿼리의 결과가 다르다. (non-repeatable read)
  3. 이전에 없었던 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 하기 이전까지 조회를 제외한 어떠한 작업도 할 수 없기 때문에

  1. 아직 COMMIT 하지 않은 신뢰 할 수 없는 데이터를 읽어온다. (dirty read)
  2. 한 트랜잭션에서 동일한 SELECT 쿼리의 결과가 다르다. (non-repeatable read)
  3. 이전에 없었던 SELECT 쿼리 결과에 없던 값이 생성된다. (phantom read)

세 가지 일은 발생할 일이 없다.


References

https://jupiny.com/2018/11/30/mysql-transaction-isolation-levels/

 

MySQL의 Transaction Isolation Levels

사실 이 글의 목적은 데이터베이스의 Transaction Isolation Levels에 대해 공부한 내용을 쓰기 위함이었는데, MySQL을 예로 사용하며 여러가지 실습해보며 MySQL에서만 적용되는 몇가지 특성이 있음을 알게 되었고, 제목에다가 "MySQL"을 붙이게 되었다. 아래 4가지 Transaction Isolation Levels에 대해 공부한 내용을 각각 나누어 적어보았다. READ UNCOMMITTED READ COMMITTED REPEAT

jupiny.com

https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html#isolevel_repeatable-read

 

MySQL :: MySQL 8.0 Reference Manual :: 15.7.2.1 Transaction Isolation Levels

15.7.2.1 Transaction Isolation Levels Transaction isolation is one of the foundations of database processing. Isolation is the I in the acronym ACID; the isolation level is the setting that fine-tunes the balance between performance and reliability, consis

dev.mysql.com

 

'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