che01 님의 블로그
트랜잭션 격리수준 (Transaction Isolation Levels) 본문
트랜잭션 격리수준 (Transaction Isolation Levels)
격리수준이란?
여러 트랜잭션이 동시에 실행될 때 데이터의 정합성과 일관성을 얼마나 보장할 것인지를 설정하는 기준이다. 격리 수준이 낮을수록 동시성 성능은 좋아지지만 데이터 정합성이 깨질 수 있다.
4가지 격리수준
1. READ UNCOMMITTED (레벨 0)
- 다른 트랜잭션에서 아직 커밋하지 않은 데이터도 읽을 수 있음
- 가장 낮은 격리 수준으로 성능은 좋지만 데이터 정합성 문제 발생 가능
- 발생 가능한 문제: Dirty Read, Non-repeatable Read, Phantom Read
2. READ COMMITTED (레벨 1)
- 커밋된 데이터만 읽을 수 있음
- 대부분의 DBMS에서 기본값으로 설정
- 발생 가능한 문제: Non-repeatable Read, Phantom Read
3. REPEATABLE READ (레벨 2)
- 같은 트랜잭션 내에서 같은 쿼리 결과는 항상 동일하게 보장
- MySQL InnoDB의 기본 격리 수준
- 발생 가능한 문제: Phantom Read
4. SERIALIZABLE (레벨 3)
- 가장 엄격한 수준으로 트랜잭션을 순차적으로 실행한 것과 동일한 결과 보장
- 모든 동시성 문제를 방지하지만 성능이 가장 낮음
- 발생 가능한 문제: 없음
동시성 문제점
Dirty Read
다른 트랜잭션에서 아직 커밋하지 않은 데이터를 읽는 현상
-- 트랜잭션 A
BEGIN;
UPDATE accounts SET balance = 500 WHERE id = 1; -- 1000 → 500 변경
-- 아직 COMMIT 하지 않음
-- 트랜잭션 B (동시 실행)
SELECT balance FROM accounts WHERE id = 1; -- 500을 읽음 (Dirty Read)
-- 트랜잭션 A
ROLLBACK; -- 실제로는 원복됨, 하지만 B는 잘못된 데이터를 읽었음
Non-repeatable Read
같은 트랜잭션에서 같은 쿼리를 두 번 실행했을 때 결과가 다른 현상
-- 트랜잭션 A
BEGIN;
SELECT balance FROM accounts WHERE id = 1; -- 1000 조회
-- 트랜잭션 B (동시 실행)
BEGIN;
UPDATE accounts SET balance = 500 WHERE id = 1;
COMMIT;
-- 트랜잭션 A (계속)
SELECT balance FROM accounts WHERE id = 1; -- 500 조회 (이전과 다름)
COMMIT;
Phantom Read
같은 조건의 SELECT를 반복했는데 행의 개수나 내용이 달라지는 현상
-- 트랜잭션 A
BEGIN;
SELECT COUNT(*) FROM products WHERE price > 1000; -- 결과: 5개
-- 트랜잭션 B (동시 실행)
BEGIN;
INSERT INTO products (name, price) VALUES ('새상품', 1500);
COMMIT;
-- 트랜잭션 A (계속)
SELECT COUNT(*) FROM products WHERE price > 1000; -- 결과: 6개 (Phantom Read)
COMMIT;
격리수준별 문제 발생 가능성
격리수준 Dirty Read Non-repeatable Read Phantom Read
| 격리수준 | Dirty Read | Non-repeatable | Phantom Read | |
| READ UNCOMMITTED | O | O | O | |
| READ COMMITTED | X | O | O | |
| REPEATABLE READ | X | X | O | |
| SERIALIZABLE | X | X | X |
격리수준 설정
MySQL
-- 세션 레벨
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- 글로벌 레벨
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
PostgreSQL
-- 트랜잭션 시작 시
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
'Spring' 카테고리의 다른 글
| Spring @EnableScheduling과 @Scheduled 동작 원리 (0) | 2025.07.13 |
|---|---|
| Spring @Async 비동기 처리와 프록시 (4) | 2025.07.10 |
| Self-invocation Problem (0) | 2025.06.24 |
| JPA N+1 문제 완벽 해결하기 - EntityGraph를 활용한 성능 최적화 (0) | 2025.06.10 |
| JPA 상속관계 매핑 전략 완전 정리 (2) | 2025.06.09 |