데이터베이스 용어 사전
트랜잭션isolation level · READ COMMITTED · REPEATABLE READ · SERIALIZABLE

격리수준

동시 트랜잭션의 간섭을 어디까지 막을지 정하는 단계. 같은 이름이어도 PostgreSQL과 MySQL의 구현이 다르다.

동시 트랜잭션이 서로 얼마나 간섭하도록 허용할지를 정하는 단계. 위로 갈수록 안전하고 동시성은 낮다.

표준 네 단계 — 무엇을 막나

격리수준Dirty ReadNon-repeatable ReadPhantom Read
READ UNCOMMITTED가능가능가능
READ COMMITTED막음가능가능
REPEATABLE READ막음막음가능(표준상)
SERIALIZABLE막음막음막음

표준은 현상을 막는 최소 기준만 정하고 구현은 DB마다 다르다. 실무에서 가장 자주 어긋나는 지점이 여기다.

같은 이름, 다른 동작

  • [PostgreSQL] — 기본값 READ COMMITTED

    • 매 문장마다 새 스냅샷 → 문장 단위로 커밋된 데이터만 본다
    • READ UNCOMMITTED 를 요청해도 READ COMMITTED 로 동작 (dirty read 자체를 안 한다)
    • REPEATABLE READ = 스냅샷 격리 → 트랜잭션 시작 시점 스냅샷을 끝까지 봐
      • phantom 까지 막는다 (표준보다 강하다). 단 write skew 는 남는다
    • SERIALIZABLE = SSI → 직렬화 이상을 탐지해 한쪽을 롤백시킨다
  • [MySQL InnoDB] — 기본값 REPEATABLE READ

    • 갭 락·넥스트키 락으로 phantom 도 상당히 막는다
    • READ COMMITTED 도 흔히 쓴다 (복제·락 경합을 줄이려고)

"REPEATABLE READ"라는 같은 이름이어도 PostgreSQL은 스냅샷, MySQL은 락으로 구현한다. 동작도 실패 양상도 다르다.

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;   -- 트랜잭션 단위로 지정

실무 원칙

기본(READ COMMITTED)에서 시작한다
  ↓ 갱신 손실·write skew 가 실제로 문제되는 지점만
FOR UPDATE · 버전 칼럼 · SERIALIZABLE 로 올린다

전체를 SERIALIZABLE로 올리는 건 대개 과하다. SERIALIZABLE과 낙관적 락에는 재시도 로직이 짝이다 — 직렬화 실패는 예외가 아니라 정상 흐름이다.

면접 함정

  • "REPEATABLE READ면 phantom이 생긴다"표준상 그렇고, PostgreSQL·MySQL 실제 구현에서는 막힌다.
  • "격리수준을 올리면 Lost Update도 막힌다" → SERIALIZABLE이 아니면 별도 처리(비관/낙관 락)가 필요하다.

지금 무엇으로 돌고 있나

-- PostgreSQL
SHOW default_transaction_isolation;    -- read committed
SELECT current_setting('transaction_isolation');

-- MySQL
SELECT @@global.transaction_isolation, @@session.transaction_isolation;
-- REPEATABLE-READ (기본)

프레임워크가 커넥션 풀 설정으로 이 값을 바꿔 두는 경우가 있어, 애플리케이션에서 실제로 무엇이 적용되는지 확인하는 게 먼저다.

직접 실험해 보는 법

-- 터미널 두 개로 각각 실행한다
-- [세션 1]
BEGIN ISOLATION LEVEL REPEATABLE READ;
SELECT count(*) FROM orders WHERE amount > 1000;   -- 10

-- [세션 2]
INSERT INTO orders (amount) VALUES (5000); COMMIT;

-- [세션 1]
SELECT count(*) FROM orders WHERE amount > 1000;
-- PostgreSQL → 10 (스냅샷이라 새 행이 안 보인다)
-- MySQL      → 10 (일관된 읽기)
COMMIT;

문서를 읽는 것보다 두 세션을 띄워 직접 확인하는 것이 격리수준을 이해하는 가장 빠른 길이다.

격리를 올리면 무엇을 감수하나

  • READ COMMITTED — 락 경합 적음 · 처리량 높음 · 이상현상 일부 허용
  • REPEATABLE READ — MySQL 은 갭 락으로 락 범위가 넓어진다 → 데드락 증가
  • SERIALIZABLE — PostgreSQL 은 직렬화 실패 오류가 늘어난다 → 재시도 필수

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 트랜잭션 — ACID·격리수준·이상현상(PostgreSQL·MySQL)