Isolation(격리성)
여러 트랜잭션이 동시에 수행될 떄, 각 트랜잭셔이 다른 트랜잭션의 중간 작업을 참조하지 못하게 막는 것
격리성이 보장되지 않을 때 발생하는 문제들
1. Dirty Read
- 다른 트랜잭션이 아직 커밋하지 않은 데이터를 읽는 것
- 읽은 데이터가 롤백되는 경우 잘못된 정보를 사용하게 됨
예: 트랜잭션 A가 계좌 잔액을 500 → 100으로 수정했지만 아직 커밋 전.
트랜잭션 B가 그 100을 보고 다른 작업을 실행 → 이후 A가 롤백하면 잘못된 데이터를 기반으로 한 작업 발생
2. Non-Repeatable Read
- 같은 쿼리를 두 번 실행했을 때, 그 사이에 다른 트랜잭션이 데이터를 변경해서 결과가 달라지는 경우
예: 트랜잭션 A가 상품 가격을 조회 → 트랜잭션 B가 그 가격을 수정하고 커밋 → 트랜잭션 A가 다시 같은 상품 가격을 조회했더니 값이 달라짐
3. Phantom Read
- 같은 조건으로 여러 번 쿼리했는데, 사이에 다른 트랜잭션이 행을 추가/삭제해서 결과 행 수가 바뀌는 경우
예: WHERE price > 1000으로 조회했더니 5개 → 트랜잭션 B가 새로 상품 추가 → 다시 같은 조건으로 조회했더니 6개로 늘어남
Isolation Level(트랜잭션 격리 수준)
| 수준 | Dirty Read | Non-Repeatable Read | Phantom Read |
|---|
| READ UNCOMMITTED | ❌ 허용 | ❌ 허용 | ❌ 허용 |
| READ COMMITTED | ✅ 차단 | ❌ 허용 | ❌ 허용 |
| REPEATABLE READ | ✅ 차단 | ✅ 차단 | ❌ 허용 (MySQL에서는 차단) |
| SERIALIZABLE | ✅ 차단 | ✅ 차단 | ✅ 차단 |
각 수준 설명
1. READ UNCOMMITTED
- 가장 낮은 격리 수준
- 다른 트랜잭션이 커밋하지 않은 데이터를 읽을 수 있음 → Dirty Read 허용
- 거의 사용되지 않음 (데이터 무결성 보장이 안됨)
2. READ COMMITTED (기본값: Oracle, PostgreSQL)
- 커밋된 데이터만 읽음
- Dirty Read는 방지되지만, Non-Repeatable Read나 Phantom Read는 발생 가능
- 일반적인 트랜잭션 처리에 적합
3. REPEATABLE READ (기본값: MySQL InnoDB)
- 한 트랜잭션 내에서 같은 데이터를 여러 번 읽어도 결과가 같음
- Non-Repeatable Read는 방지됨
- 하지만 Phantom Read는 방지되지 않음
(다만 MySQL InnoDB는 이를 의도적으로 막기도 함)
- 데이터 정합성이 중요한 경우 사용
4. SERIALIZABLE
- 가장 강력한 격리 수준
- 트랜잭션을 완전히 순차적으로 실행하는 것처럼 보이게 함
- Phantom Read까지 모두 차단됨
- 대신 성능 저하 큼, 병렬 처리 어려움
- 정합성을 최우선으로 생각하거나, 경쟁이 적은 환경에서 사용