MySQL 8.0 을 기준으로 작성되었습니다.
Transaction Isolation level
Transaction Isolation level
이란 다른 Transaction 에서 접근해 데이터를 변경하거나 조회할 수 있도록 하는 수준입니다.
예를들어 현재 실행중인 Transaction_A, 그 다음 실행된 Transaction_B 가 있다고 가정하겠습니다.
Transaction_A 의 격리 수준을 높이면 Transaction_B 가 방해할 여지가 줄어들게 됩니다.
그러면 데이터의 일관성(Consistency)
이 높아집니다.
하지만 Transaction_A 가 끝날때까지 Transaction_B 는 대기해야합니다.
그래서 동시성(Concurrency)
은 감소합니다.
반대로 Transaction_A 의 격리 수준을 낮추면, Transaction_B 가 방해할 여지가 생깁니다.
그러면 데이터의 일관성(Consistency)
은 낮아집니다.
하지만, Transaction_B 가 대기할 필요가 없기 때문에, 동시성(Concurrency)
은 증가합니다.
이를 그래프로 표현한 것이 아래 그래프입니다.
위 예시의 설명과 같이 Isolation leve 에 따라 변화하는 일관성(Consistency)
과 동시성(Concurrency)
을 나타내는 그래프 입니다.
그림에서 보시다시피 Isolation level 은 4종류가 있습니다.
- READ UNCOMMITTED
- READ COMMITED
- REPEATABLE READ
- SERIALIZE
격리 수준이 낮은 순서대로 특징을 살펴보겠습니다.
READ UNCOMMITTED
- COMMIT 되지 않은 데이터에 다른 Transaction 이 접근 가능
- INSERT, UPDATE, DELETE 후 COMMIT 혹은 ROLLBACK 여부에 상관없이 현재 테이터를 조회함
- ROLLBACK 이 될 예정인 데이터를 조회할 수 있어서 주의가 필요함
- LOCK 이 발생하지 않음
위 내용을 한마디로 요약하면, 무조건 현재 가장 최신 테이터를 조회 한다고 이해할 수 있습니다.
LOCK 이 발생하지 않기 때문에, Transaction 의 대기시간을 줄일 수 있지만 무결성을 해칠 가능성이 높은 Isolaction level 입니다.
이는 dirty read*
라고도 하며, 반대 개념으로는 consistent read*
가 있습니다.
dirty read
다른 Transaction 에 의해 변경되었지만 COMMIT 되지 않은 데이터를 조회하는 작업입니다.
신뢰할 수 없는 데이터이며, READ UNCOMMITTED 격리 수준에서만 가능합니다.consistent read(Consistent Nonlocking read)
InnoDB 가 여러 버전의 데이터베이스 스냅샷을 제공하는 읽기 방법입니다.
즉, consistent read 를 실행하면 다른 Transaction 의 COMMIT 이 반영된 최신 snapshot 을 생성하고 이를 기준으로 읽기를 실행합니다.
그러나 트랜잭션 내에서 여러번 consistent read 가 발생하면, 각자의 snapshot 을 생성하여 읽어옵니다.
그래서 이렇게 생성된 snapshot 은 실제 DB 에는 존재한적 없는 테이블 형태가 될 수 있습니다.참고
READ COMMITTED
스냅샷을 Transaction 내에서 공유하는 REPEATABLE READ
와는 다르게 동일한 Transaction 내에서도 각 일관된 읽기(consistent read) 쿼리는 자체 스냅샷을 생성하여 읽습니다.
READ COMMITTED
는 아래와 같은 특징이 있습니다.
- Locking read*, UPDATE, DELETE 쿼리 실행시 locking 이 발생함
해당하는 index record 에 대해 record lock 이 발생합니다.
gap lock 이 발생하지 않기 때문에,... WHERE c1 BETWEEN 10 and 20 FOR UPDATE
같은 locking read 쿼리가 발생하더라도 다른 트랜잭션이 c1 컬럼에 대해 15번을 입력하거나
수정하는것이 가능합니다. - MySQL에서 많은 양의 데이터를 복제하거나 이동할 때 이 LEVEL을 추천함
locking read
SELECT ... FOR UPDATE
다른 트랜잭션에서 데이터를 변경 하려는 행위를 기다리게합니다.SELECT ... FOR SHARE
orSELECT ... LOCK IN SHARE MODE
다른 트랜잭션에서 데이터를 읽거나 변경하려는 행위를 기다리게합니다.
기존에는LOCK IN SHARE MODE
가 사용되었으나 8.0 부터는FOR SHARE
키워드로 대체되었습니다.
하지만 호환성을 위해 두 키워드 모두 사용 가능합니다.
REPEATABLE READ
REPEATABLE READ
는 InnoDB 의 기본 Isolation level 로 설정되어있으며, 다음과 같은 특징이 있습니다.
- Transaction 내에서 처음 조회한 데이터로 스냅샷을 생성함
이후 조회시에는 생성된 스냅샷을 조회함 - 동일 트랜잭션 내에서 일관성 보장
- Locking read, UPDATE, DELETE 쿼리 실행시 locking 이 발생함
unique index 로 특정 데이터를 검색하는지, 범위를 검색하는지에 따라 해당 index record 들에 대해record lock
혹은gap lock*
이 발생합니다.- 특정 데이터 검색 : record lock 이 발생함
- 범위 검색 : gap lock* 이 발생함
gap lock
Index record 들의 범위를 lock 함.
예를들어
SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;
쿼리를 실행하면
10~20 인덱스가 lock 상태가 됩니다.
만약 여기서 다른 트랜잭션이 c1 컬럼에 대해 15번을 입력하거나 수정하는것이 불가합니다.
즉, 15번이 존재하는지와는 관계없이 10~20 범위는 무조건 lock 상태가 됩니다.
- 입력 예 :
INSERT INTO t (c1) VALUES (15);
- 수정 예 :
UPDATE t SET c1=15 WHERE id=15;
참고 : MySQL 8.0 gap lock
SERIALIZE
SERIALIZE
격리 수준은 REPEATABLE READ
와 비슷하지만 auto commit 설정 여부에 따라 다르게 동작합니다.
- auto commit 비활성화
암묵적으로 모든SELECT
를SELECT ... FOR SHARE
로 변환합니다. - auto commit 활성화
모든SELECT
가 자체 Transaction 을 가집니다.
이런 동작방식은read only
로 알려져있습니다.
그리고 다른 Transaction 에 의해 차단되지 않은consistent read
라면, - 주로
XA Transaction*
이 사용되는 환경에서 동시성과 교착상태 문제를 해결하는데 주로 쓰입니다.
XA Transaction
분산환경에서의 트랜잭션을 위한 표준 인터페이스입니다.
ACID complience*
를 유지하며 여러 데이터베이스가 하나의 Transaction 에 참여할 수 있습니다.ACID complience
Database Transaction 이 적시에 완료되는것을 보장하기 위한 4가지 특성을 말합니다.
- Atomicity : 원자성
- Consistency : 일관성
- Isolation : 격리성
- Durability : 내구성(장애 복구)
참고