Transaction Isolation Level

무지성개발자·2023년 9월 23일
0

Transaction Isolation Level

Transaction Isolation Level은 트랜잭션이 동시에 변경하고 쿼리를 수행할 때 성능, 안전성, 일관성, 결과 재현성 사이의 균형을 조정하는 설정이다.

  • READ UNCOMMITTED
  • READ COMMITTED
  • REFEATABLE READ
  • SERIALIZALE

4단계로 나뉘며 위에 있을 수록 동시성 처리에 유리하고 아래에 있을 수록 데이터 정합성이 높다.

Isolation Level과 Test

테스트는 MySQL + workbench로 했으며 workbench은 세션(탭)을 2개 띄워서 사용했음. 샘플로 사용할 iso_tb다.

READ UNCOMMITTED

  • Commit 되지 않은 변경된 데이터를 SELECT로 볼 수 있을 정도 격리 수준.
    • Rollback 전후로 SELECT를 한 작업이 있다면 데이터가 일관되지 않음.
    • Dirty Read, non-Repeatable Read, Phantom Read가 발생.
// 두 세션 각각 실행하여 격리레벨을 바꾸기
set session transaction isolation level READ UNCOMMITTED;
// 격리 레벨 확인
select @@session.transaction_isolation;

//1번 세션에서
START TRANSACTION;
UPDATE iso_tb SET name = '판교' WHERE seq = 1;

// 2번 세션에서 -> saq = 1이 강남이 판교로 보임.
START TRANSACTION;
SELECT * FROM iso_tb;

//1번 세션에서
ROLLBACK; //반드시 롤백해야함

// 2번 세션에서 -> seq = 1이 다시 강남으로 보임.
SELECT * FROM iso_tb;
COMMIT;

READ COMMITTED

  • Commit되지 않은 변경된 데이터는 읽지 않음.
    • 커밋 전까진 undo영역의 데이터의 데이터를 읽어 더티리드가 발생하지 않음.
    • 하나의 트랜잭션 Commit 전.후로 select하는 작업을 가진 트랜잭션은 데이터가 일치 하지 않는 문제 발생.(데이터 정합성 깨짐)
    • 한 트랜잭션에서 select 값은 항상 일치해야하는데 그렇지 못한 non-Repeatable Read 발생, Phantom Read 발생.
// 두 세션 각각 실행하여 격리레벨을 바꾸기
set session transaction isolation level READ COMMITTED;
// 격리 레벨 확인
select @@session.transaction_isolation;

//1번 세션에서
START TRANSACTION;
UPDATE iso_tb SET name = '판교' WHERE seq = 1;

// 2번 세션에서 -> 커밋 전이라 saq = 1이 강남이 변경된 판교로 보이지 않음.
START TRANSACTION;
SELECT * FROM iso_tb;

//1번 세션에서
COMMIT;

// 2번 세션에서 -> 커밋 후라 saq = 1이 강남이 판교로 보임.
SELECT * FROM iso_tb;

//2번 세션에서
COMMIT;

REPEATABLE READ

// 두 세션 각각 실행하여 격리레벨을 바꾸기
set session transaction isolation level REPEATABLE READ;
// 격리 레벨 확인
select @@session.transaction_isolation;

//1번 세션에서
start TRANSACTION;
UPDATE iso_tb SET name = '판교' WHERE seq = 1;

//2번 세션에서 -> seq = 1이 강남이 변경된 판교로 보이지 않음.
start TRANSACTION;
SELECT * FROM iso_tb;

//1번 세션에서
COMMIT;

// 2번 세션에서 -> 커밋을 해도 saq = 1이 강남이 변경된 판교로 보이지 않음.
SELECT * FROM iso_tb;
COMMIT;

// 2번 세션에서 -> 이제 saq = 1이 강남이 변경된 판교로 보임.
SELECT * FROM iso_tb;

SERIALIZABLE

  • 가장 강력한 격리 수준의 격리로 한 트랜잭션이 락을 얻으면 다른 트랜잭션이 접근을 할 수 없음.
// 두 세션 각각 실행하여 격리레벨을 바꾸기
set session transaction isolation level SERIALIZABLE;
// 격리 레벨 확인
select @@session.transaction_isolation;

//2번 세션에서
START TRANSACTION;
SELECT * FROM iso_tb;

//1번 세션에서 -> 2번 세션에서 lock을 획득하고 있어서 변경이 안되고 대기.
START TRANSACTION;
UPDATE iso_tb SET name = '판교' WHERE seq = 1;

// 2번 세션에서 -> 1번 세션 변경사항 적용됨.
COMMIT;

// 1번 세션에서
COMMIT;

한 줄평 : MySQL에 따르면 REPEATABLE READ > READ COMMITTED > READ UNCOMMITTED > SERIALIZABLE 순서로 많이 쓴다고 한다.

참고 -
https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html

profile
no-intelli 개발자 입니다. 그래도 intellij는 씁니다.

0개의 댓글