티스토리 뷰
트랜잭션 격리 수준(Isolation Level) 종류와 이상 현상 및 예제 총정리
1. 트랜잭션 격리 수준(Isolation Level) 개요
트랜잭션 격리 수준(Isolation Level)이란 동시에 여러 트랜잭션이 처리될 때, 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있도록 허용할지 말지를 결정하는 설정입니다.
격리 수준이 높을수록 데이터 일관성은 엄격하게 보장되지만, 동시 처리 성능(Throughput)은 떨어지는 트레이드 오프 관계를 가집니다. ANSI/ISO SQL 표준에서 정의한 격리 수준은 총 4가지 단계로 나뉩니다.
| 격리 수준 (Isolation Level) | Dirty Read | Non-Repeatable Read | Phantom Read |
|---|---|---|---|
| READ UNCOMMITTED | 발생 가능 | 발생 가능 | 발생 가능 |
| READ COMMITTED | 방지 가능 | 발생 가능 | 발생 가능 |
| REPEATABLE READ | 방지 가능 | 방지 가능 | 발생 가능 (MySQL은 방지) |
| SERIALIZABLE | 방지 가능 | 방지 가능 | 방지 가능 |
2. 동시성 저하로 발생하는 3대 데이터 이상 현상과 예제
① Dirty Read (더티 리드)
정의: 다른 트랜잭션이 수정 중이지만 아직 커밋(Commit)하지 않은 데이터를 읽는 현상입니다. 만약 해당 트랜잭션이 롤백(Rollback)되면 무효가 된 가짜 데이터를 신뢰하는 심각한 정합성 오류가 생깁니다.
-- 트랜잭션 A (금액 수정 작업 시작)
START TRANSACTION;
UPDATE accounts SET balance = 50000 WHERE id = 1;
-- ⚠️ 아직 COMMIT 안 함
-- 트랜잭션 B (조회 시작)
SELECT balance FROM accounts WHERE id = 1;
-- 🛑 결과: 50000 조회 완료 (Dirty Read 발생)
-- 트랜잭션 A에 에러가 발생하여 롤백 처리
ROLLBACK;
-- 결과적으로 트랜잭션 B는 세상에 존재하지 않는 금액 50000을 읽어 사용하게 됨
② Non-Repeatable Read (반복 불가능한 조회)
정의: 한 트랜잭션 안에서 같은 조회를 여러 번 실행했을 때, 중간에 다른 트랜잭션이 값을 수정(Update)하고 커밋해 버려 1번째 결과와 2번째 결과가 다르게 나타나는 현상입니다.
-- 트랜잭션 A (1번째 조회)
START TRANSACTION;
SELECT points FROM users WHERE id = 1; -- ⭕ 결과: 100
-- 트랜잭션 B (중간에 데이터 수정 후 커밋)
START TRANSACTION;
UPDATE users SET points = 200 WHERE id = 1;
COMMIT;
-- 트랜잭션 A (동일 트랜잭션 내부에서 2번째 조회)
SELECT points FROM users WHERE id = 1;
-- 🛑 결과: 200 조회 (하나의 트랜잭션 내 조회가 불일치하는 Non-Repeatable Read 발생)
COMMIT;
③ Phantom Read (팬텀 리드)
정의: 단일 데이터가 변하는 것이 아니라, 조건부 범위 조회를 수행했을 때 다른 트랜잭션이 데이터를 삽입(Insert)하고 커밋하는 바람에 이전에 없던 새로운 유령(Phantom) 레코드가 나타나는 현상입니다.
-- 트랜잭션 A (범위 조건 조회 1차)
START TRANSACTION;
SELECT * FROM employees WHERE salary >= 5000; -- ⭕ 결과: 3건 조회
-- 트랜잭션 B (조건 범위에 해당하는 신규 데이터 삽입)
START TRANSACTION;
INSERT INTO employees (id, name, salary) VALUES (10, 'Kim', 6000);
COMMIT;
-- 트랜잭션 A (범위 조건 조회 2차)
SELECT * FROM employees WHERE salary >= 5000;
-- 🛑 결과: 4건 조회 (신규 데이터 Kim이 유령처럼 추가되어 나타나는 Phantom Read 발생)
COMMIT;
3. RDBMS별 MVCC와 격리 수준 구현 방식의 차이점
실무에서 가장 널리 쓰이는 **MySQL(InnoDB)**과 **PostgreSQL / Oracle**은 격리 수준을 다루는 내부 메커니즘에서 중요한 차이점을 보입니다. 핵심은 잠금(Locking) 없이 동시성을 확보하는 기술인 **MVCC (Multi-Version Concurrency Control)**입니다.
- MySQL InnoDB의 REPEATABLE READ: 하이버네이트나 일반 구글링 문서와 달리, MySQL InnoDB 엔진은 REPEATABLE READ 단계에서도 Phantom Read가 발생하지 않습니다. 락을 걸지 않을 때는 언두 로그(Undo Log)의 스냅샷을 활용한 MVCC 비잠금 읽기를 지원하고, 락을 거는 조회(
FOR UPDATE등)에서는 넥스트 키 락(Next-Key Lock, 레코드 락과 갭 락의 결합)을 사용해 새로운 데이터 삽입 자체를 차단하기 때문입니다. - Oracle / PostgreSQL의 기본 수준: 두 데이터베이스의 기본 격리 레벨은 READ COMMITTED입니다. 따라서 하나의 트랜잭션 내에서 반복적으로 SELECT를 호출할 때 데이터가 변할 수 있음을 상정하고 방어적 코드(비관적 락 등)를 고려해야 합니다.
#트랜잭션격리수준 #DirtyRead예제 #NonRepeatableRead #PhantomRead원인 #MVCC원리 #MySQL격리수준 #데이터베이스동시성 #RDBMS성능최적화
'Program Development' 카테고리의 다른 글
| React DOM 최적화 (0) | 2026.06.13 |
|---|---|
| VSCode 설치 방법(Windows, MacOS) (0) | 2026.06.11 |
| 컴파일 vs 인터프리터 (1) | 2026.06.10 |
| 메시지 큐(MQ), Kafka, RabbitMQ 아키텍처 내부 원리 (0) | 2026.06.08 |
| 프로그래밍 언어별 주석 처리 방법 총정리 (0) | 2026.06.02 |
| HTTP 상태 코드(HTTP Status Codes) (0) | 2026.05.16 |
| C# 소켓 프로그래밍 - 비동기 채팅 프로그램 만들기 (1:n 통신) (13) | 2018.08.31 |
| [C#] 자동차 번호판 인식 프로그램 with Tesseract-OCR, OpenALPR (27) | 2018.08.22 |
- Total
- Today
- Yesterday
- 클래스
- C언어
- 문자열
- 안드로이드
- String
- C
- 파일처리
- MySQL
- OpenCV
- 블루투스
- 문제풀이
- 자바
- 데이터베이스
- 알고리즘
- c#
- C++
- html
- C++ 클래스
- 아두이노
- 상속
- Android
- 정보처리기사
- 배열
- 리스트
- 벡터
- 파이썬
- Java
- Class
- 자료구조
- DB연동
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
