← 아티클 목록

트랜잭션 격리수준 4가지 — 쉽게 이해하기

2026-09-14#database#트랜잭션#동시성

여러 트랜잭션이 같은 데이터를 동시에 건드릴 때, 격리수준은 "다른 트랜잭션의 작업이 나에게 얼마나 보이는가"를 정합니다. 격리를 높이면 일관성이 올라가지만 동시성(성능)은 떨어집니다. 둘은 트레이드오프 관계입니다.

먼저 현재 값을 본다

SQL
-- MySQL
SELECT @@transaction_isolation;   -- 기본 REPEATABLE-READ

-- PostgreSQL
SHOW default_transaction_isolation;  -- 기본 read committed

4가지 격리수준과 막는 현상

낮은 수준일수록 이상 현상(anomaly)이 더 많이 발생합니다.

격리수준Dirty ReadNon-repeatable ReadPhantom Read
READ UNCOMMITTED발생발생발생
READ COMMITTED막음발생발생
REPEATABLE READ막음막음발생*
SERIALIZABLE막음막음막음

*MySQL InnoDB는 REPEATABLE READ에서 갭 락으로 팬텀까지 대부분 막습니다.

세 가지 현상이 뭔지부터

  • Dirty Read — 아직 커밋 안 된 남의 변경을 읽음. 그 트랜잭션이 롤백하면 유령 데이터를 본 셈.
  • Non-repeatable Read — 같은 행을 두 번 읽었는데 값이 다름(중간에 누가 UPDATE 커밋).
  • Phantom Read — 같은 조건으로 두 번 조회했는데 행 개수가 다름(중간에 누가 INSERT).

직접 재현해 보기

세션 A에서 갱신하고 커밋 전, 세션 B에서 읽어봅니다.

SQL
-- 세션 B
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN;
SELECT balance FROM accounts WHERE id = 1;  -- A가 커밋해야 새 값 보임
COMMIT;

READ UNCOMMITTED로 바꾸면 세션 A가 커밋하기 전에도 변경값이 보입니다(dirty read).

어떤 수준을 쓸까

TEXT
- 대부분의 웹 서비스      → READ COMMITTED (PostgreSQL 기본)
- 일관된 스냅샷이 필요     → REPEATABLE READ (MySQL 기본)
- 정산·재고처럼 정확성 최우선 → SERIALIZABLE (성능 비용 감수)

기본값을 모르고 쓰다 "읽을 때마다 값이 바뀐다"는 증상을 만나면, 십중팔구 격리수준 이해 부족입니다.


트랜잭션 두 세션을 직접 띄워 dirty read·phantom read를 재현하는 실습은 데이터베이스 트랙에서 회원가입 없이 무료로 할 수 있습니다.