짧은 연차동안 현업에서 3가지 RDBMS를 다뤄본 경험을 가지게 되었다.
이를 토대로 각 데이터베이스별 격리 수준(Isolation Level)에 따른 동작 원리와
읽기/쓰기 시 락 동작 방식을 비교하여 정리해보려 한다.
여러 트랜잭션이 동시에 처리될 때,
특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있게 허용할지 여부를 결정하는 규칙이다.
격리 수준이 낮으면 동시성(Concurrency)은 높아지지만, 데이터 정합성 문제(Dirty Read, Non-Repeatable Read, Phantom Read 등)가 발생할 가능성이 있다.
격리 수준이 높으면 데이터 일관성은 좋아지지만, 동시성 저하와 락 경합 증가가 발생할 수 있다.
MySQL InnoDB는 MVCC(Multi-Version Concurrency Control) 기반으로 동작하여 읽기 작업에서 락을 최소화하면서도, 쓰기 작업 시에는 적절한 락을 걸어 데이터 무결성을 보장한다.
| 격리 수준 | 읽기 시 락 | 쓰기 시 락 |
|---|---|---|
| Read Uncommitted | 없음 (커밋되지 않은 데이터도 읽음 → Dirty Read 발생) | 행 단위 배타락(X Lock) |
| Read Committed | 없음 (쿼리 실행 시점마다 최신 커밋 스냅샷 읽기) | 행 단위 배타락(X Lock) |
| Repeatable Read | 없음 (트랜잭션 시작 시점 MVCC 스냅샷 고정) | 행 단위 배타락(X Lock) + Next-Key Lock |
| Serializable | 암묵적 공유 락(S Lock) 적용 | 행 단위 배타락(X Lock) + Next-Key Lock 범위 유지 |
읽기 작업
쓰기 작업
SELECT ... FOR UPDATE, SELECT ... FOR SHARE 같은 Locking Read에도 적용된다.PostgreSQL은 MVCC 기반이며, 락 정책과 충돌 감지 방식에 차이가 있다.
| 격리 수준 | 읽기 시 락 | 쓰기 시 락 |
|---|---|---|
| Read Uncommitted | 지원하지 않음 (Read Committed로 동작) | 해당 없음 |
| Read Committed | 없음 (쿼리 실행 시점마다 최신 커밋 스냅샷 읽기) | 행 단위 배타락(X Lock) |
| Repeatable Read | 없음 (트랜잭션 시작 시점 MVCC 스냅샷 고정) | 행 단위 배타락(X Lock) + 쓰기 시점 버전 충돌 감지 후 롤백 |
| Serializable | 없음 (MVCC + SSI 적용) | 행 단위 배타락(X Lock) + SSI 의존성 추적으로 충돌 시 롤백 |
읽기 작업
쓰기 작업
MSSQL은 기본적으로 락 기반 동시성 제어를 사용하며, 옵션으로 MVCC 기반 Snapshot Isolation도 지원한다.
| 격리 수준 | 읽기 시 락 | 쓰기 시 락 |
|---|---|---|
| Read Uncommitted | 없음 | 없음 |
| Read Committed | 기본: 짧은 시간 동안 S Lock 유지 / RCSI 활성화 시: 없음 (MVCC 읽기) | 행 단위 배타락(X Lock) |
| Repeatable Read | S Lock을 트랜잭션 종료까지 유지 | 행 단위 배타락(X Lock)을 트랜잭션 종료까지 유지 |
| Snapshot | 없음 (MVCC 스냅샷 읽기) | 행 단위 배타락(X Lock), 충돌 시 롤백 |
| Serializable | 범위 락(Key-Range Lock) 유지 | 행 단위 배타락(X Lock) + 범위 락 유지 |
읽기 작업
READ_COMMITTED_SNAPSHOT = ON(RCSI)을 활성화하면 S Lock 없이 MVCC 스냅샷으로 읽어 동시성이 높아진다.쓰기 작업
Phantom Read는 트랜잭션 내에서 같은 조건으로 여러 번 조회할 때, 처음에는 없던 새로운 행이 다른 트랜잭션에 의해 삽입되어 결과가 달라지는 현상이다.
MySQL RR: MVCC 스냅샷 고정으로 새로 INSERT된 행이 보이지 않아 Phantom Read가 방지된다. 추가로 Next-Key Lock으로 갭을 잠가 쓰기 충돌도 차단한다.
PostgreSQL RR: 갭 락 없이 트랜잭션 시작 시점의 스냅샷이 고정되어 있어, 다른 트랜잭션이 새 row를 INSERT하고 커밋해도 보이지 않는다. 스냅샷 고정만으로 Phantom Read가 방지된다.
PostgreSQL SERIALIZABLE: SSI(Serializable Snapshot Isolation)는 Phantom Read보다 더 넓은 범위인 Write Skew까지 방지한다. 트랜잭션 간 읽기/쓰기 의존성을 추적해 직렬성 위반 가능성이 있으면 롤백한다.
MSSQL SERIALIZABLE: Key-Range Lock(범위 락)으로 조회 조건에 해당하는 인덱스 범위 전체를 잠가 새로운 행 삽입을 차단하여 Phantom Read를 방지한다.
MVCC 기반과 락 기반의 차이점
격리 수준 선택 시 고려할 점