전체 목록
데이터베이스Hard#108

데이터베이스 트랜잭션 격리 수준과 Dirty Read, Non-repeatable Read, Phantom Read를 설명해주세요.

#DB#트랜잭션#격리수준#동시성

답변 포인트

동시에 실행되는 트랜잭션이 서로의 변경을 어느 정도 볼 수 있는지 기준으로 설명해보세요.

정답 및 해설

빠른 요약

Dirty Read는 다른 트랜잭션이 커밋하지 않은 데이터를 읽는 현상입니다. Non-repeatable Read는 같은 트랜잭션에서 같은 행을 두 번 읽었는데 값이 달라지는 현상입니다.

트랜잭션 격리 수준(Isolation Level)은 동시에 실행되는 트랜잭션들이 서로의 중간 상태를 얼마나 볼 수 있는지 정하는 규칙입니다. 격리 수준이 높을수록 정합성은 좋아지지만 동시성은 낮아질 수 있습니다.

동시성 이상 현상

Dirty Read

다른 트랜잭션이 아직 커밋하지 않은 데이터를 읽는 현상입니다.

데이터베이스
T1:   1000  500 
T2:  500 
T1: 

T2는 실제로 존재하지 않게 된 값을 읽은 셈입니다.

Non-repeatable Read

같은 트랜잭션 안에서 같은 행을 두 번 읽었는데 값이 달라지는 현상입니다.

데이터베이스
T1:  A    silver
T2:  A  gold   
T1:  A     gold

한 트랜잭션 내부에서 동일한 조회 결과가 반복 가능하지 않습니다.

Phantom Read

같은 조건으로 여러 번 조회했는데, 이전에 없던 행이 새로 나타나거나 사라지는 현상입니다.

데이터베이스
T1: age >= 20    10
T2: age 25    
T1: age >= 20     11

행 단위 변경이 아니라 조건 범위에 해당하는 결과 집합이 바뀌는 문제입니다.

격리 수준

격리 수준Dirty ReadNon-repeatable ReadPhantom Read
READ UNCOMMITTED가능가능가능
READ COMMITTED방지가능가능
REPEATABLE READ방지방지DB에 따라 가능
SERIALIZABLE방지방지방지

READ COMMITTED

커밋된 데이터만 읽습니다. Dirty Read는 막지만, 다른 트랜잭션이 커밋한 변경은 다시 조회할 때 보일 수 있습니다.

SQL
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

많은 데이터베이스에서 기본 격리 수준으로 사용됩니다.

REPEATABLE READ

트랜잭션 내에서 같은 행을 반복해서 읽으면 동일한 결과를 보장합니다. MySQL InnoDB는 MVCC와 next-key lock을 통해 일부 Phantom Read도 방지합니다.

SQL
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

SERIALIZABLE

트랜잭션을 사실상 순차 실행한 것처럼 가장 강하게 격리합니다. 정합성은 높지만 락 경합과 성능 저하가 커질 수 있습니다.

SQL
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

정리

격리 수준은 정합성과 성능 사이의 트레이드오프입니다. 모든 트랜잭션을 무조건 SERIALIZABLE로 올리기보다, 비즈니스 규칙상 허용 가능한 이상 현상과 데이터베이스의 MVCC/락 동작을 이해하고 선택해야 합니다.

격리 수준을 이해하는 관점

트랜잭션 격리 수준은 동시에 실행되는 트랜잭션들이 서로를 얼마나 강하게 분리할지 정하는 규칙입니다. 격리가 강할수록 이상 현상은 줄지만 잠금/버전 관리 비용이 커질 수 있습니다.

격리 수준Dirty ReadNon-repeatable ReadPhantom Read
Read Uncommitted가능가능가능
Read Committed방지가능가능
Repeatable Read방지방지DB에 따라 가능
Serializable방지방지방지

이상 현상 예시

SQL
-- T1
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
-- 아직 COMMIT 전

-- T2가 이 값을 읽으면 Dirty Read
SELECT balance FROM accounts WHERE id = 1;

Non-repeatable Read는 같은 행을 두 번 읽었는데 중간에 다른 트랜잭션이 커밋해 값이 달라지는 경우입니다. Phantom Read는 같은 조건으로 조회했는데 중간에 조건에 맞는 행이 추가/삭제되어 결과 집합이 달라지는 경우입니다.

실무 선택

  • 일반적인 웹 서비스는 DB 기본값(Read Committed 또는 Repeatable Read)을 많이 사용합니다.
  • 결제, 재고 차감처럼 정합성이 중요한 영역은 명시적 잠금, 낙관적 락, Serializable을 검토합니다.
  • 격리 수준만 믿지 말고 유니크 제약, 외래 키, 체크 제약 같은 DB 제약조건을 함께 사용합니다.

관련 질문

같은 카테고리/태그 기준