1. 트랜잭션 격리성
트랜잭션은 데이터베이스에서 하나의 논리적 기능을 수행하기 위한 작업의 단위를 말한다.
트랜잭션에는 ACID라는 네 가지 특징이 있다. 그 중 격리성(Isolation)은 트랜잭션 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것을 의미한다.
2. 트랜잭션 격리 수준
트랜잭션 격리 수준은 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 격리되어 있는가를 나타내는 정도이다.
격리성이 커질수록 더 확실한 처리가 가능하지만, 동시에 수행될 수 있는 트랜잭션이 순서대로 처리되므로 속도가 느려지게 된다.
ANSI/ISO SQL 표준에서는 격리 수준을 READ_UNCOMMITED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE 4가지로 나누고 있다.
MySQL은 REPEATABLE_READ, Oracle은 READ_COMMITTED가 기본 격리 수준으로 설정되어 있다.
아래 사진은 명령어를 사용하여 현재 진행 중인 프로젝트의 격리 수준을 확인해본 결과이다.
1) SERIALIZABLE
매우 엄격한 수준으로, 말 그대로 트랜잭션을 순차적으로 진행시켜야 한다. (그동안 다른 트랜잭션은 기다려야 한다.)
격리성이 제일 높지만, 교착 상태가 일어날 확률이 많고 가장 성능이 떨어진다.
2) REPEATABLE READ
특정 행을 조회할 때, 항상 같은 데이터를 응답하는 것을 보장하는 격리 수준이다.
하나의 트랜잭션이 수정한 행을 다른 트랜잭션이 수정할 수 없도록 막아준다. 그러나 새로운 행을 추가하는 것은 막지 않기 때문에 이후에 추가된 행이 발견될 수 있다.
3) READ COMMITTED
커밋이 완료된 트랜잭션의 변경사항만 다른 트랜잭션이 조회할 수 있도록 허용하는 격리 수준이다.
그러나 어떤 트랜잭션이 접근한 행을 다른 트랜잭션이 수정하는 것은 가능하다.
4) READ UNCOMMITTED
커밋이 되지 않은 트랜잭션의 데이터 변경을 달느 트랜잭션이 조회하는 것을 허용하는 격리 수준이다. 격리 수준이 가장 낮지만 속도가 제일 빠르다.
데이터 무결성을 위해 되도록이면 사용하지 않는 것이 바람직하지만, 몇몇 행이 제대로 조회되지 않더라도 괜찮은 거대한 양의 데이터를 '어림잡아' 집계하는 데 사용하면 좋다.
3. 트랜잭션 격리 수준에 따라 발생할 수 있는 문제점
격리 수준에 따라 팬텀 리드(Phantom Read), 반복 가능하지 않은 조회(Non-Repeatable Read), 더티 리드(Dirty Read)라는 현상이 발생할 수 있다.
1) 팬텀 리드 (Phantom Read)
한 트랜잭션 내에서 동일한 쿼리를 보냈을 때 해당 조회 결과가 다른 경우를 의미한다.
위 예시를 보자. 사건이 일어나는 순서는 아래와 같다.
- Transaction 1에서 나이가 12 이상인 회원을 조회한다
- Transaction 2에서 나이가 15인 회원 B를 추가한다
- Transaction 1에서 나이가 12 이상인 회원을 조회한다
1번과 3번 과정은 동일한 쿼리를 보낸 상황인데, 조회 결과가 다른 것을 볼 수 있다.
Serializable을 제외한 모든 격리 수준(Repeatable Read, Read Committed, Read Uncommitted)에서 발생하는 문제이다.
2) 반복 가능하지 않은 조회(Non-Repeatable Read)
한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 경우를 의미한다.
격리 수준이 Read Committed, Read Uncommitted일 때 발생한다.
Phantom Read vs Non-Repeatable Read?
팬텀 리드는 INSERT나 DELETE 쿼리에 의해 다른 행이 선택되어 데이터 정합성이 깨지는 것을 의미하고,
반복 가능하지 않은 조회는 UPDATE 쿼리에 의해 행 값이 변경되어 데이터 정합성이 깨지는 것이다.
3) 더티 리드(Dirty Read)
한 트랜잭션이 실행 중일 때 다른 트랜잭션에 의해 수정되었지만 아직 '커밋되지 않은' 행의 데이터를 읽을 수 있을 때 발생한다.
격리 수준이 Read Uncommitted일 때 발생한다.
마지막 2개의 단계를 보면 Transaction 2가 Commit되기 전에 Transaction 1에서 Select를 했는데 아직 커밋하지 않은 결과가 조회되고 있다.
4. 정리
이제까지 살펴본 격리 수준과 격리 수준에 따라 발생하는 문제를 정리하면 아래 표와 같다.
격리 수준 | Phantom Read | Non-Repeatable Read | Dirty Read |
Serializable | ❌ | ❌ | ❌ |
Repeatable Read | ⭕️ | ❌ | ❌ |
Read Committed | ⭕️ | ⭕️ | ❌ |
Read Uncommited | ⭕️ | ⭕️ | ⭕️ |
Reference
- 면접을 위한 CS 전공지식 노트
- https://hudi.blog/transaction-isolation-level/