백엔드 면접 용어 사전
데이터베이스isolation level

격리수준

동시 트랜잭션이 서로를 얼마나 볼 수 있는지 정하는 단계. READ UNCOMMITTED~SERIALIZABLE 네 수준.

동시 실행되는 트랜잭션이 서로의 작업을 얼마나 볼 수 있는지 정하는 단계. 격리를 강하게 할수록 안전하지만 동시성이 떨어진다.

네 단계와 이상현상

수준Dirty ReadNon-Repeatable ReadPhantom Read
READ UNCOMMITTED발생발생발생
READ COMMITTED차단발생발생
REPEATABLE READ차단차단발생(이론상)
SERIALIZABLE차단차단차단

세 이상현상의 차이

Dirty Read            : 커밋 안 된 값을 읽음        (롤백되면 유령 데이터)
Non-Repeatable Read   : 같은 행을 두 번 읽으니 값이 다름   (UPDATE 때문)
Phantom Read          : 같은 조건으로 두 번 읽으니 행 수가 다름 (INSERT 때문)

앞의 둘은 행 단위 문제이고, 팬텀은 범위 문제다. 행 락으로는 팬텀을 막을 수 없다 — 없는 행을 미리 잠글 수 없기 때문이다.

DB별 기본값 — 자주 묻는다

DB기본 격리수준
MySQL(InnoDB)REPEATABLE READ
PostgreSQL · Oracle · SQL ServerREAD COMMITTED

MySQL만 다르다. 역사적으로 복제(statement 기반 binlog)의 정합성 때문에 높게 잡은 것이 이어졌다.

MySQL의 REPEATABLE READ는 팬텀도 거의 막는다

InnoDB는 넥스트 키 락(레코드 락 + 갭 락)으로 행 사이의 빈 공간까지 잠근다.

인덱스:  … 10 ── (갭) ── 20 ── (갭) ── 30 …
                  ↑
        WHERE age > 15 조건이면 이 갭도 잠가
        age=17 을 새로 INSERT 하려는 트랜잭션을 막는다

그래서 이론상 허용되는 팬텀이 실제로는 잘 안 생긴다. 대가는 데드락 증가다 — 잠그는 범위가 넓어지니 충돌이 잦아진다.

무엇을 고르나

대부분 기본값을 그대로 쓰고, 정합성이 중요한 특정 구간만 다르게 다룬다.

  • 격리수준을 올리는 것보다
  • 낙관적 락(버전 컬럼)
  • 조건부 UPDATE (WHERE status = 'PENDING')
  • 유니크 제약
  • 쪽이 범위가 좁아 성능에 유리하다

격리수준은 트랜잭션 전체에 걸리지만, 위 방법들은 필요한 행에만 걸리기 때문이다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 데이터베이스 — 인덱스·트랜잭션·격리수준·N+1