트랜잭션 격리 수준 (Transaction Isolation Level)
트랜잭션 격리 수준에 대해 알아보겠습니다.
트랜잭션에 대해 궁금하다면
이전에 포스팅된 트랜잭션을 확인해 주세요.
트랜잭션 격리 수준 이란?
트랜잭션끼리 일관된 데이터를 얼마나 허용할 것 인지 정하는 수준입니다.
격리 수준에는 총 4개의 레벨이 존재합니다.
격리 수준의 레벨
Read uncommitted - 커밋되지 않은 데이터 읽기
Read committed - 커밋된 데이터만 읽기 (대부분의 DB의 Default Isolation Level)
Repeatable Read - 읽는 동안 수정/삭제 불가능 (MySQL의 Default Isolation Level)
Serializable - 완벽한 일관성 모드를 제공한다. 이상 현상이 발생하지 않는다.
또 각각의 단계 별로 일어날 수 있는 현상들로는 3개의 현상이 존재합니다.
격리 수준의 이상 현상
Dirty Read - 커밋되지 않은 수정된 데이터를 다른 트랜잭션에서 읽을 수 있을 때 발생하는 현상
격리 수준의 레벨 중 'Read uncommitted' 레벨에서 발생합니다.
Non-Repeatable Read - 하나의 트랜잭션에서 같은 데이터를 두 번 읽는 도중에 다른 트랜잭션에서 해당 데이터를 수정하면서 발생하는 현상으로 격리 수준의 레벨 중 'Read uncommitted', 'Read committed'에서 발생합니다.
Phantom Read - 하나의 트랜잭션에서 일정 범위의 레코드를 두 번 이상 읽었을 때, 첫 번째 쿼리에서 없던 레코드가 두 번째 쿼리에서 나타나는 현상 즉, 수정/삭제 가 아닌 추가에 의한 현상으로 격리 수준의 레벨 중 'Read uncommitted', 'Read committed', 'Repeatable Read'에서 발생합니다.
이렇게 글로만 봐서는 각각 격리 수준에서 어떠한 이상 현상들이 벌어지는지 알 수 없습니다.
시퀀스 다이어그램을 통해 하나씩 살펴보겠습니다.
Read uncommitted (level 0)
Select 문장이 실행될 때 Lock이 걸리지 않습니다.
위 그림에서와 같이 Transaction 1이 수정후 커밋되지 않은 데이터를 Transaction 2에서 조회할 수 있습니다. (Dirty Read 발생)
해당 레벨에서는 다른 이상 현상 (Non-Repeatable Read, Phantom Read) 도 함께 발생합니다.
Read committed (level 1)
대부분의 DB에서 Default로 사용하고 있는 격리 수준입니다.
Read committed 레벨에서는 타 트랜잭션의 수정/삭제에 대한 영향을 받지 않습니다.
위의 그림에서 보면 Transaction 1. 이 데이터를 수정하여도, Transaction 2. 는 UNDO에 백업된 데이터를 가져오기 때문에
영향을 받지 않습니다.
하지만 Transaction 1 이 커밋된 후 Transaction 2에서 다시 조회한다면 Commit 된 결과가 조회되어 Transaction 2의 두 Select 결과가 다르게 됩니다. 그 외에도 Phantom read 현상도 발생합니다.
Repeatable Read (level 2)
MySql에서 사용하는 격리 수준입니다.
자신보다 높은 Transaction ID를 가진 Transaction에 대해서는 항상 UNDO 영역의 백업된 데이터를 읽게 되어
Non-Repeatable Read 가 발생하지 않습니다!
하지만 위 그림과 같이 Transaction 1이 Commit 되면, Transaction 2에는 데이터 추가에 의한 Phantom Read가 발생합니다.
첫 Select 결과와 두번 째 Select 결과의 개수가 다르게 됩니다.
Serializable (level 3)
가장 엄격한 격리 수준입니다.
level 0, 1, 2 에서 일어나는 모든 현상이 일어나지 않습니다.
동시성이 떨어져서 잘 사용되지 않습니다. 동시성이 떨어진 다는 것은
특정 트랜잭션이 데이터를 읽고 있다면 추가/수정/삭제가 불가능합니다.
정리하자면?
현상 \ 격리 수준 | Read uncommited | Read commited | Repeatable read | Serializable |
Dirty Read | O | X | X | X |
Non-Repeatable Read | O | O | X | X |
Phantom Read | O | O | O | X |
위의 표와 같이 정리할 수 있습니다.
격리 수준을 수정할 때는 동시성과 일관성 사이에서 현재 서비스에 맞는 수준을 찾는 것이 중요할 것 같습니다.