트랜잭션 격리 수준 완벽 가이드



데이터베이스 트랜잭션 격리 수준(Isolation Level)은 동시에 실행되는 트랜잭션 간의 데이터 일관성을 제어합니다. 각 수준의 특징과 발생 가능한 문제를 알아봅니다.



1. 격리 수준 종류









격리 수준Dirty ReadNon-RepeatablePhantom
READ UNCOMMITTEDOOO
READ COMMITTEDXOO
REPEATABLE READXXO
SERIALIZABLEXXX


2. 문제 유형 설명



Dirty Read (더티 리드)
- 커밋되지 않은 데이터를 읽음
- 롤백되면 잘못된 데이터 사용

Non-Repeatable Read (반복 불가능 읽기)
- 같은 쿼리가 다른 결과 반환
- 다른 트랜잭션이 UPDATE 후 커밋

Phantom Read (팬텀 리드)
- 같은 조건으로 조회 시 행 수가 달라짐
- 다른 트랜잭션이 INSERT/DELETE 후 커밋


3. READ UNCOMMITTED



-- 가장 낮은 격리 수준
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

-- 커밋 안된 데이터도 읽음
-- 성능 최고, 일관성 최저
-- 사용 사례: 대략적인 통계, 로그 조회


4. READ COMMITTED (대부분 DB 기본값)



-- Oracle, SQL Server 기본값
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 커밋된 데이터만 읽음
-- 같은 쿼리도 결과가 달라질 수 있음
-- 사용 사례: 일반적인 OLTP 환경


5. REPEATABLE READ



-- MySQL InnoDB 기본값
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

-- 트랜잭션 시작 시점 스냅샷 사용
-- 같은 쿼리는 같은 결과 보장
-- 사용 사례: 보고서, 정산 처리


6. SERIALIZABLE



-- 가장 높은 격리 수준
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

-- 완벽한 격리, 순차 실행처럼 동작
-- 성능 저하, 데드락 가능성 높음
-- 사용 사례: 금융 거래, 재고 관리


7. 실전 예시: MySQL



-- 현재 격리 수준 확인
SELECT @@transaction_isolation;

-- 세션 격리 수준 변경
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

-- 글로벌 변경
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;


8. 실전 예시: Oracle



-- Oracle은 READ COMMITTED와 SERIALIZABLE만 지원
ALTER SESSION SET ISOLATION_LEVEL = SERIALIZABLE;

-- 트랜잭션별 설정
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;


9. Spring에서 설정



@Transactional(isolation = Isolation.READ_COMMITTED)
public void processOrder() {
// ...
}

@Transactional(isolation = Isolation.REPEATABLE_READ)
public void generateReport() {
// ...
}


선택 가이드




  • 일반 웹 서비스: READ COMMITTED

  • 보고서/정산: REPEATABLE READ

  • 재고/결제: SERIALIZABLE (또는 비관적 락)

  • 로그 조회: READ UNCOMMITTED