트랜잭션 격리 수준(Isolation level)은 동시에 실행되는 트랜잭션이 처리될 때 트랜잭션끼리의 간섭을 나타내는 것이다.
격리 수준
격리수준은 크게
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE 이 네 가지가 있으며, 위에서 아래로 갈 수록 점점 높은 격리 수준을 의미한다. 격리 수준은 높을 수록 데이터 일관성은 보장되지만 트레이드오프로 성능은 떨어지는 관계가 있다.
1. READ UNCOMMITTED
- 가장 낮은 격리 수준
- 커밋되지 않은 데이터도 읽을 수 있음
- Dirty Read, Non-repeatable Read, Phantom Read 모두 발생 가능
- 성능은 가장 좋지만 데이터 일관성 문제가 많음
- 똑같은 select를 수행하면 똑같은 결과를 반환해야 한다는 repeatable read 반환하는 데이터는 불가능
Dirty Read 다른 트랜잭션이 아직 커밋하지 않은 데이터를 읽음
Non-Repeatable Read 같은 조건의 쿼리를 실행했을 때 이전에 없던 새로운 행이 나타남
Phantom Read 같은 조건의 쿼리를 실행했을 때 이전에 없던 새로운 행이 나타남
**2. READ COMMITTED **
- (트랜잭션이 시작되기 전) 커밋된 데이터만 읽을 수 있음
- Dirty Read는 방지하지만 Non-repeatable Read, Phantom Read는 발생 가능
- 대부분의 DBMS에서 기본 격리 수준으로 사용
- ORACLE
3. REPEATABLE READ
- 트랜잭션 내에서 같은 데이터를 여러 번 읽어도 동일한 결과 보장
- Dirty Read, Non-repeatable Read 방지
- Phantom Read는 여전히 발생 가능
- MySQL InnoDB의 기본 격리 수준
4. SERIALIZABLE
- 가장 높은 격리 수준
- 모든 이상 현상 방지
- 트랜잭션들이 순차적으로 실행되는 것과 동일한 결과 보장
- 성능이 가장 떨어지지만 완전한 데이터 일관성 제공
동시성 문제들
Dirty Read
- 다른 트랜잭션이 아직 커밋하지 않은 데이터를 읽음
시간 | 트랜잭션 A | 트랜잭션 B
-----|------------------------------|----------------
T1 | BEGIN |
T2 | UPDATE 계좌 SET 잔액=1000 |
T3 | | BEGIN
T4 | | SELECT 잔액 FROM 계좌 → 1000 읽음
T5 | ROLLBACK |
T6 | | (잘못된 데이터 1000으로 작업 진행)
Non-repeatable Read (반복 불가능한 읽기)
- 같은 트랜잭션 내에서 같은 데이터를 여러 번 읽었을 때 다른 값이 나오는 현상
시간 | 트랜잭션 A | 트랜잭션 B
-----|------------------------------|----------------
T1 | BEGIN |
T2 | SELECT 잔액 FROM 계좌 → 500 |
T3 | | BEGIN
T4 | | UPDATE 계좌 SET 잔액=1000
T5 | | COMMIT
T6 | SELECT 잔액 FROM 계좌 → 1000 |
T7 | (같은 데이터인데 다른 값!) |
위 예시와 같이 트랜잭션 A가 같은 데이터를 두 번 읽었는데 다른 값이 나왔다.
Phantom Read (팬텀 리드)
- 같은 조건의 쿼리를 실행했을 때 이전에 없던 새로운 행이 나타나거나 기존 행이 사라지는 현상
시간 | 트랜잭션 A | 트랜잭션 B
-----|--------------------------------------|----------------
T1 | BEGIN |
T2 | SELECT * FROM 주문 |
| WHERE 날짜='2024-01-01' → 3건 |
T3 | | BEGIN
T4 | | INSERT INTO 주문 VALUES(...)
T5 | | (날짜='2024-01-01')
T6 | | COMMIT
T7 | SELECT * FROM 주문 |
| WHERE 날짜='2024-01-01' → 4건 |
T8 | (새로운 행이 나타남!) |
위 예시와 같이 트랜잭션 A가 같은 조건으로 검색했는데 첫 번째는 3건, 두 번째는 4건이 나오게 됨.