본문 바로가기
TWIL

MariaDB의 READ COMMITTED vs REPEATABLE READ 격리 수준과 부정합 문제들

by swims 2025. 3. 30.

자주 사용되는 MariaDB의 READ COMMITTED와 REPEATABLE READ의 차이는 무엇이고, 어떤 문제가 각각 발생할 수 있을까?

 

🔍 READ COMMITTED

  • 항상 "커밋된 최신 데이터"를 조회한다.
  • 다른 트랜잭션에서 커밋된 최신 결과가 반영됨

발생 가능한 문제:

  1. ❗ Non-Repeatable Read → 같은 row를 두 번 조회했을 때 중간에 다른 트랜잭션이 값을 바꾸면 다른 값이 반환됨
  2. ❗ Phantom Read → 같은 조건으로 select했을 때 중간에 insert(커밋)된 row로 인해 row 개수가 달라짐
  3. ❗ Lost Update → 두 트랜잭션이 같은 데이터를 수정하고 한 쪽이 덮어쓰는 문제

 

 

🔍 REPEATABLE READ (MariaDB의 기본 설정)

  • 트랜잭션 시작 시점의 커밋된 데이터를 기준으로 스냅샷을 생성하고 트랜잭션이 커밋될 때까지 고정됨

방지되는 문제:

  1. ✅ Non-Repeatable Read 방지 → 한 번 읽은 row는 트랜잭션 내에서 계속 같은 값을 유지
  2. ✅ Phantom Read 방지 (MariaDB) → 인덱스 범위까지 스냅샷으로 관리되므로, 중간에 삽입된 row도 보이지 않음
  3. ❗ 단, Lost Update는 여전히 발생 가능 → 단순 select만 수행한 경우 락이 걸리지 않기 때문에, 커밋 시점이 다른 경우 발생 할 수 있음

 

격리 수준이 높아질수록 읽기의 일관성은 보장되지만, 쓰기 간 충돌(Lost Update)을 완전히 막지는 못한다.

부정합 문제 READ COMMITTED REPEATABLE READ
Dirty Read 방지됨 방지됨
Non-Repeatable Read 방지됨 방지됨
Phantom Read 발생 가능 방지됨

 

 

앞서 발생한 lost update를 READ COMMITTED, REPEATABLE READ 격리 수준에서 각각 설명하면 다음과 같다

  설명 READ COMMITTED REPEATABLE READ
1 트랜잭션 A가 객체 단순 조회 (SELECT) 커밋된 최신 데이터 읽음 스냅샷 생성 (트랜잭션 시작 시점 기준 커밋된 데이터)
2 트랜잭션 B도 객체 단순 조회 동일하게 커밋된 최신 데이터 읽음 동일하게 스냅샷 기준 데이터 읽음
3 트랜잭션 B가 먼저 커밋 커밋 가능 (락 없음) 커밋 가능 (락 없음)
4 트랜잭션 A가 커밋 (JPA 더티 체킹) B의 변경사항을 덮어씀 → ❗ Lost Update B의 변경사항을 덮어씀 → ❗ Lost Update
🔁 (4-1) A가 커밋 전 같은 객체를 다시 조회한 경우 다른 값 조회됨 (다른 트랜잭션 커밋 반영됨) 처음 조회한 값 그대로 유지됨 (스냅샷 기반)
✅ 특징 커밋된 최신값을 매번 참조 트랜잭션 내 조회 결과 고정