변수의 기록

(데이터베이스) 트랜잭션 이상현상과 격리 수준 (SQL-92 표준 기반) 본문

CS지식/데이터베이스 (Database)

(데이터베이스) 트랜잭션 이상현상과 격리 수준 (SQL-92 표준 기반)

불광동 물주먹 2025. 5. 23. 16:10

✅트랜잭션 이상현상과 격리 수준 (SQL-92 표준 기반)

💡 트랜잭션에서 왜 "이상현상"이 발생할까?

트랜잭션이 동시에 실행되면, 읽기/쓰기 충돌로 인해 **예상하지 못한 결과(= 이상현상)**가 발생할 수 있습니다.
이를 방지하기 위해 SQL-92에서는 **3가지 대표적인 이상현상(anomalies)**을 정의하고, 이를 제어할 수 있도록 **4단계 격리 수준(Isolation Level)**을 표준화했습니다.


✅ SQL-92 이상현상 3가지

 

구분 설명
1. Dirty Read A 트랜잭션이 아직 커밋하지 않은 데이터를 B가 읽는 현상
2. Non-Repeatable Read A 트랜잭션이 같은 row를 두 번 읽는데 중간에 값이 변경되어 결과가 다르게 나옴
3. Phantom Read A 트랜잭션에서 같은 조건으로 SELECT 했는데, 중간에 다른 트랜잭션이 INSERT/DELETE 해서 row 개수가 달라짐
 

✅ SQL-92 격리 수준 4단계


 

수준 설명 방지 가능한 이상현상
1. READ UNCOMMITTED 커밋되지 않은 데이터도 읽을 수 있음 ❌ 아무것도 방지 못함
2. READ COMMITTED 커밋된 데이터만 읽음. SELECT할 때마다 최신 스냅샷 생성 ✅ Dirty Read만 방지
3. REPEATABLE READ 트랜잭션 시작 시점의 Snapshot 기준으로 모든 SELECT 수행 ✅ Dirty Read, ✅ Non-Repeatable Read 방지
❌ Phantom Read 발생 가능
4. SERIALIZABLE 트랜잭션을 직렬화된 순서처럼 실행. Snapshot 고정 + 충돌 감지 ✅ 3가지 이상현상 모두 방지 (가장 엄격하고 안전)
 

🧠 핵심 요약

  • REPEATABLE READ"같은 row를 반복 조회했을 때 값이 바뀌지 않게 보장"
    → 하지만 **범위 기반 삽입/삭제(Phantom)**는 감지 못함
  • SERIALIZABLE읽기/쓰기 모든 충돌을 감지해서 강제 롤백
    → 가장 안전하지만 성능 부담 있음

✅오라클 트랜잭션 격리 수준과 이상현상 정리

Oracle은 SQL-92의 4단계 중 2단계만 지원합니다:

✅ Oracle이 지원하는 격리 수준

 

수준 설명
1. READ COMMITTED (기본값) 각 SELECT마다 최신 커밋된 데이터 기준 스냅샷을 생성
2. SERIALIZABLE 트랜잭션 시작 시 스냅샷 고정 + 쓰기 간섭 발생 시 예외(ORA-08177) 발생
 

✅ Oracle에서 이상현상 방지 여부


 

이상현상 READ COMMITTED SERIALIZABLE
Dirty Read ✅ 방지됨 ✅ 방지됨
Non-Repeatable Read ❌ 발생 가능 ✅ 방지됨
Phantom Read ❌ 발생 가능 ✅ 방지됨
Write Skew ❌ 발생 가능 ✅ 방지됨 (예외 발생 및 롤백 처리)
 

✅ Oracle 실무에서 주로 사용하는 방법


방법 설명
SELECT ... FOR UPDATE 특정 row에 명시적으로 Lock을 걸어 동시 수정 방지
FOR UPDATE NOWAIT / WAIT n / SKIP LOCKED 실시간 트랜잭션 제어 전략 가능 (즉시 실패, 대기 제한, 락 건너뛰기 등)
SERIALIZABLE 일부 마감 처리, 월별 집계 등 중요한 연산에만 사용 (충돌 시 강제 롤백)
 

🔑 Oracle 정리 포인트

  • READ COMMITTED + 명시적 Lock (FOR UPDATE) 조합이 실무 기본
  • SERIALIZABLE은 안전하지만 충돌/성능 부담 존재
  • Oracle은 Undo 기반 MVCC를 이용해 정합성을 강하게 보장