17.1 트랜잭션 개념 (Transaction Concept)
트랜잭션은 데이터베이스 시스템에서 일관성(consistency)과 신뢰성(reliability)을 보장하는 기본 단위다.
정의 (Definition)
- 트랜잭션
(Transaction) - 여러 data item에 접근하고 갱신하는 하나의 프로그램 실행 단위(a unit of program execution).
트랜잭션이 다뤄야 할 두 가지 핵심 문제:
- Failures — 하드웨어 고장·시스템 충돌 등 장애.
- Concurrent execution — 여러 트랜잭션의 동시 실행.
예제: Fund Transfer (A → B, $50)
// T_i: A 계좌에서 B 계좌로 $50 이체 read(A); A := A - 50; write(A); read(B); B := B + 50; write(B);
이 6개 연산은 "전부 반영되거나 전혀 반영되지 않아야" 하며, 도중에 A+B 합이 깨져 보여서도 안 된다.
ACID 요구사항 (Requirements)
위 이체 예제를 통해 왜 네 가지 보장이 필요한지 정리한다.
Atomicity (원자성)
트랜잭션의 부분 실행 결과가 DB에 반영되어서는 안 된다. write(A) 직후 장애가 나면 $50이 사라진 상태가 남으면 안 된다.
Durability (지속성)
트랜잭션 완료를 사용자에게 통보한 뒤에는, 이후 장애가 발생해도 그 갱신이 유지되어야 한다.
Consistency (일관성)
트랜잭션 전후로 A+B 합이 불변이어야 한다. explicit(예: 무결성 제약)·implicit 일관성 제약을 모두 보존.
Isolation (격리성)
다른 동시 트랜잭션이 부분 갱신된 DB에 접근하지 못해야 한다. serial 실행이면 자명하나, 성능 때문에 동시 실행이 필요하다.
이체 전 상태 (A=900, B=300) → 이체 후 (A=850, B=350). 합 1200이 그대로 보존된다. 트랜잭션 도중에는 합이 1150처럼 보일 수 있으나, 이는 외부에 노출되어서는 안 된다(Isolation).
17.2 ACID 속성
트랜잭션이 보장해야 하는 네 가지 성질. 각 정의를 정확히 외우는 것이 핵심.
A Atomicity
All or Nothing. 트랜잭션의 모든 연산이 DB에 반영되거나, 전혀 반영되지 않거나 둘 중 하나다.
C Consistency
고립 실행(in isolation)되는 트랜잭션은 데이터베이스의 일관성을 보존한다.
I Isolation = Serializability
각 트랜잭션은 다른 동시 트랜잭션의 존재를 인지하지 못한다. 중간 결과(intermediate result)는 다른 트랜잭션에 숨겨진다.
D Durability
트랜잭션이 성공적으로 완료되면, 이후 시스템 장애가 발생해도 그 변경은 유지된다.
Atomicity = All or Nothing · Consistency = 고립 실행이 일관성 보존 · Isolation = Serializability(다른 TX를 인지 못함, 중간 결과 은닉) · Durability = 성공 후 장애에도 변경 유지. 특히 I = Serializability라는 점을 정확히.
17.3 트랜잭션 상태 (Transaction States)
트랜잭션은 실행되며 5개의 상태를 거친다. 정상 경로와 실패 경로를 구분하는 것이 핵심.
5개 상태
- Active
- 초기 상태. 실행 중(executing)인 상태.
- Partially
committed - 마지막 명령(final statement)을 실행한 직후.
- Failed
- 정상 진행이 불가능함을 발견한 후.
- Aborted
- 롤백(rollback)을 마쳐 트랜잭션 이전 상태로 복원된 후 → 재시작(restart) 또는 폐기(kill).
- Committed
- 성공적으로 완료(successful completion)된 후.
상태 전이 (Transitions)
- active → partially committed → committed (정상 경로)
- active → failed
- partially committed → failed
- failed → aborted
aborted 후에는 재시작하거나(restart) 그대로 종료(kill)한다.
인터랙티브: 트랜잭션 상태 머신
"재생 ▶"은 정상 경로를, "실패 경로"는 장애 경로를 애니메이션한다. 현재 상태가 강조 표시된다.
17.4 스케줄 (Schedules)
동시 실행되는 트랜잭션들의 명령을 시간 순서로 나열한 것.
정의 & 규칙
- Schedule
- 동시 실행 트랜잭션들의 명령에 대한 시간순 실행 순서(chronological order).
- 모든 트랜잭션의 모든 명령을 포함해야 한다.
- 각 트랜잭션 내부의 명령 순서는 보존되어야 한다.
- 각 트랜잭션의 마지막 명령은 Commit(성공) 또는 Abort(실패).
예제 트랜잭션
- T1
- A에서 B로 $50 이체.
- T2
- A의 10%를 B로 이체.
- Schedule 1: T1 다음 T2 (serial)
- Schedule 2: T2 다음 T1 (serial)
- Schedule 3: 인터리빙이지만 Schedule 1과 equivalent → serializable
- Schedule 4: 인터리빙, A+B 보존 안 됨 → not serializable
활용도(utilization)↑ · 처리량(throughput)↑, 그리고 대기 시간(waiting time)↓ · 응답 시간(response time)↓. serial 실행은 안전하지만 자원 낭비가 크다.
인터랙티브: Schedule 3 vs Schedule 4 실행 추적
초기값 A=1000, B=2000. "다음 ▶"으로 한 연산씩 진행하며 A·B 값 변화를 추적한다. Schedule 3은 A+B를 보존하지만 Schedule 4는 깨뜨린다.
17.5 직렬가능성 (Serializability)
인터리빙된 스케줄이 어떤 serial 스케줄과 "동일한 효과"를 내면 직렬가능하다. 그 판정 기준이 conflict다.
Conflicting Instructions (충돌하는 명령)
서로 다른 트랜잭션 Tᵢ, Tⱼ가 같은 항목 Q에 접근하고 적어도 하나가 write이면 두 명령은 충돌한다.
| Tᵢ의 명령 | Tⱼ의 명령 | 충돌? | 의미 |
|---|---|---|---|
| read(Q) | read(Q) | 비충돌 | 둘 다 읽기만 → 순서 무관 |
| read(Q) | write(Q) | 충돌 | 읽은 값이 달라질 수 있음 |
| write(Q) | read(Q) | 충돌 | 무엇을 읽는지 달라짐 |
| write(Q) | write(Q) | 충돌 | 최종 값이 달라짐 |
같은 항목 Q에 둘 다 접근 & ≥1이 write면 conflict. R-R만 비충돌이고 R-W · W-R · W-W는 모두 충돌. 충돌하는 명령은 순서가 결과를 바꾸므로 순서가 강제되고, 비충돌 명령은 swap해도 결과가 동일하다.
Conflict Equivalent
스케줄 S를, 인접한 비충돌(non-conflicting) 명령들을 swap하는 연산만으로 S'로 변환할 수 있으면 S와 S'는 conflict equivalent하다.
Conflict Serializable
어떤 스케줄이 하나의 serial 스케줄과 conflict equivalent하면 그 스케줄은 conflict serializable하다.
T3: read(A) ; T4: write(A) ; T3: read(A) — T4의 write가 T3의 두 read 사이에 끼어, 어떤 swap으로도 serial 형태로 만들 수 없다.
17.6 선행 그래프 (Precedence Graph)
conflict serializability를 기계적으로 판정하는 도구. 정점=트랜잭션, 간선=충돌 순서.
작도 규칙 (Construction)
- 정점(vertex) = 각 트랜잭션.
- Tᵢ와 Tⱼ의 명령이 충돌하고 Tᵢ가 먼저 접근하면 간선 Tᵢ → Tⱼ를 그린다.
- 간선에 충돌한 항목(item)을 라벨로 붙일 수 있다.
판정 (Test)
- acyclic(비순환) ⟺ conflict serializable.
- acyclic이면 topological sort로 직렬화 순서(serializability order)를 얻는다 (여러 개 가능).
- cycle(순환)이 있으면 conflict serializable 아님. 예: T1↔T2 양방향 간선.
① 작도 규칙: 충돌하고 먼저 접근한 Tᵢ → Tⱼ. ② conflict serializable ⟺ precedence graph가 acyclic. ③ acyclic이면 topological sort가 직렬화 순서다(유일하지 않을 수 있음).
★ 선행 그래프 시뮬레이터 (Centerpiece)
프리셋을 고르거나 연산을 직접 추가/삭제해 스케줄을 만들면, 충돌을 분석해 선행 그래프(SVG)를 그리고 cycle을 검출해 직렬가능 여부와 직렬화 순서를 보여준다.
스케줄 (실행 순서)
선행 그래프
17.7 View Serializability 보충
conflict serializability보다 더 넓은 직렬가능성 개념. 읽은 값과 최종 값에만 주목한다.
View Equivalent — 세 조건
두 스케줄 S, S'가 다음 3조건을 모두 만족하면 view equivalent하다.
- ① Initial read 동일: S에서 Tᵢ가 Q의 초기값을 읽으면, S'에서도 Tᵢ가 Q의 초기값을 읽는다.
- ② Read-from(W→R) 보존: S에서 Tᵢ가 Tⱼ가 쓴 Q를 읽으면, S'에서도 Tᵢ는 Tⱼ가 쓴 Q를 읽는다.
- ③ Final write 동일: S에서 Q에 마지막으로 write한 트랜잭션은, S'에서도 Q에 마지막으로 write한다.
어떤 스케줄이 serial 스케줄과 view equivalent하면 view serializable하다.
포함 관계 & 성질
- conflict serializable ⊆ view serializable (역은 성립하지 않음).
- view serializability 판정은 NP-complete.
- conflict는 아니지만 view serializable한 스케줄에는 항상 blind write(read 없이 write)가 존재.
예: T3: R(Q); T4: W(Q); T3: W(Q); T5: W(Q) — T4·T5의 W(Q)가 blind write.
포함 관계 다이어그램
View(바깥 원): 더 많은 스케줄 허용 → 고동시성·고성능이지만 테스트가 어렵다(NP-complete). Conflict(안쪽 원): 더 엄격 → 저동시성·저성능이지만 테스트가 쉽다(선행 그래프 acyclic 검사). 실제 시스템은 검사 가능한 conflict serializability를 주로 사용한다.
17.8 복구 가능성 (Recoverability)
직렬가능성은 동시성의 정확성을, 복구 가능성은 장애 시 commit 순서의 정확성을 다룬다.
Recoverable
Tⱼ가 Tᵢ가 쓴 데이터를 읽었다면, Tᵢ의 commit이 Tⱼ의 commit보다 먼저 일어나는 스케줄.
Cascading Rollback
한 트랜잭션의 실패가 연쇄 롤백을 유발(T10 abort → T11, T12 롤백). recoverable하더라도 발생할 수 있어 바람직하지 않다.
Cascadeless
Tⱼ가 Tᵢ가 쓴 것을 읽으면 Tᵢ의 commit이 Tⱼ의 read보다 먼저. 모든 cascadeless ⊆ recoverable.
T8: W(A) ; T9: R(A), T9 Commit ; 이후 T8 abort → T9는 이미 commit되어 되돌릴 수 없는데 존재하지 않을 값을 읽고 커밋했으므로 복구 불가. (T8이 T9보다 먼저 commit했어야 함.)
Recoverable: Tⱼ가 Tᵢ의 데이터를 읽으면 Tᵢ commit이 Tⱼ commit보다 먼저. Cascadeless: Tᵢ commit이 Tⱼ read보다 먼저. cascadeless ⊆ recoverable (cascadeless가 더 강한 조건).
17.9 격리 수준 (Isolation Levels)
완전한 serializability는 비싸므로, SQL은 약한 격리를 허용해 동시성을 높인다. 그 대가로 이상 현상(anomaly)이 나타난다.
4가지 이상 현상 (Anomalies)
Dirty Read
아직 commit되지 않은 쓰기 값을 읽음.
Nonrepeatable Read
같은 point query를 두 번 했는데 값이 다름.
Phantom Read
같은 range query를 두 번 했는데 새 레코드가 등장.
Serialization Anomaly
commit 결과가 어떤 직렬 순서와도 불일치.
tuple-level locking은 새로 삽입되는 튜플을 미리 잠글 수 없어 phantom read가 발생한다. 같은 범위를 다시 조회하면 다른 트랜잭션이 삽입한 새 레코드("유령")가 나타난다.
인터랙티브: 격리 수준 × 이상 현상 (4×4)
행(격리 수준)을 클릭하면 강조되고 설명이 표시된다. 약함 → 강함 순. 초록=Not Possible, 빨강=Allowed/Possible.
Read uncommitted: Dirty Allowed, 나머지 Possible. Read committed: Dirty만 막음. Repeatable read: Dirty·Nonrepeatable 막지만 Phantom Allowed. Serializable: 전부 Not Possible. 강도순: Read uncommitted < Read committed < Repeatable read < Serializable.
각 수준 메모
- Serializable
- 기본 격리 수준(SQL92 / SQLite). 모든 이상 현상 방지.
- Repeatable read
- MySQL 기본. 같은 레코드 재읽기는 동일하나 phantom 여지.
- Read committed
- commit된 값만 읽음. 재읽기 값은 달라질 수 있음.
- Read uncommitted
- commit 안 된 값도 읽음(가장 약함).
SQL 설정
-- 트랜잭션 종료 COMMIT WORK; ROLLBACK WORK; -- 격리 수준 설정 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
JDBC에서 auto-commit 해제: setAutocommit(false). 이후 명시적 commit/rollback 필요.
17.10 직렬가능성 이론 심화 (Serializability Theory) 보충
"왜 acyclic이면 conflict serializable인가"를 증명 직관으로, 그리고 conflict / view / serializable의 엄밀한 포함 관계를 정리한다.
핵심 정리 (Theorem)
정리. 스케줄 S가 conflict serializable ⟺ S의 선행 그래프(precedence graph)가 acyclic이다.
아래는 엄밀한 형식 증명이 아니라, 시험에서 서술할 수 있는 증명 직관(proof sketch)이다.
① 충돌이 곧 간선 = "강제된 순서"
conflict serializable의 정의는 "인접한 비충돌 명령만 swap해서 어떤 serial 스케줄로 변환 가능"이다. 비충돌 명령은 swap해도 결과가 같으므로 자유롭게 옮길 수 있다. 반대로 충돌하는 두 명령은 순서를 바꾸면 결과가 달라지므로 상대 순서가 고정된다.
즉 Tᵢ가 Q에 먼저 접근하고 Tⱼ와 충돌하면, 어떤 동치 serial 스케줄에서도 Tᵢ가 Tⱼ보다 앞서야 한다. 이 "Tᵢ는 Tⱼ보다 먼저"라는 제약이 곧 간선 Tᵢ → Tⱼ다. 선행 그래프는 이런 강제 순서들의 집합이다.
② acyclic ⇒ serializable / cycle ⇒ 모순
(⇐) acyclic이면: 방향 그래프가 비순환이면 항상 위상 정렬(topological sort)이 존재한다. 모든 간선 Tᵢ→Tⱼ를 동시에 만족하는 트랜잭션 전순서를 얻을 수 있고, 그 순서대로 트랜잭션을 직렬 실행하면 모든 충돌 순서가 보존된다 → S와 conflict equivalent한 serial 스케줄이 존재 → conflict serializable.
(⇒) cycle이면: Tᵢ→Tⱼ→…→Tᵢ 처럼 순환이 있으면 "Tᵢ가 Tⱼ보다 먼저"이면서 동시에 "Tⱼ가 …를 거쳐 Tᵢ보다 먼저"여야 한다 — 전순서로 환원 불가능(모순). 어떤 직렬 순서로도 못 만든다 → conflict serializable 아님.
3-트랜잭션 예제: 작도 → cycle 판정 → 위상 정렬
스케줄 S = W₁(A) ; R₂(A) ; W₂(B) ; R₃(B) ; W₃(Q) (T1·T2·T3). 아래 선행 그래프 시뮬레이터의 "3-트랜잭션 예제" 프리셋과 동일하다.
1단계 · 충돌 작도
W₁(A)·R₂(A)→ W-R 충돌, T1 먼저 ⇒ T1 → T2W₂(B)·R₃(B)→ W-R 충돌, T2 먼저 ⇒ T2 → T3- Q는 T3만 접근 → 간선 없음
2단계 · cycle 판정
간선은 T1 → T2 → T3 뿐. 되돌아오는 간선이 없으므로 acyclic. ⇒ conflict serializable 확정.
3단계 · 위상 정렬
선형 사슬이므로 직렬화 순서는 T1 ; T2 ; T3 하나로 유일하다. (간선이 더 적었다면 여러 순서가 가능 — 아래 콜아웃 참고.)
충돌 = 강제된 상대 순서 = 간선. acyclic이면 위상 정렬이 그 순서를 모두 만족하는 동치 serial 스케줄을 주고, cycle이면 "A보다 먼저이면서 A보다 나중"이라는 모순이라 어떤 직렬 순서로도 환원 불가. 그래서 두 명제가 동치다.
View Serializability 판정은 왜 NP-complete인가
blind write와 조합 폭발
conflict serializability는 선행 그래프 acyclic 검사로 다항 시간에 끝난다. 그러나 view serializability는 blind write(읽지 않고 바로 write) 때문에 final-write 조건을 만족시킬 후보 직렬 순서가 폭발적으로 늘어난다.
read-from / final-write 제약을 모두 만족하는 트랜잭션 순서를 찾는 문제는 polygraph(방향이 미확정인 간선 쌍 중 하나를 고르는 그래프)의 acyclic 방향 배정 문제로 환원되며, 이는 NP-complete로 알려져 있다.
엄밀 포함: conflict ⊊ view ⊊ serializable
- conflict ⊊ view: 모든 conflict serializable은 view serializable. 역은 거짓 — blind write를 포함하는 view serializable 스케줄은 conflict serializable이 아닐 수 있다.
- view ⊊ (모든 serializable): view serializable은 "결과가 어떤 serial과 같음"을 충돌·읽기·쓰기 구조로 포착하지만, 값 의미(semantics)까지 보는 더 넓은 직렬가능성은 포착하지 못한다.
- 각 ⊊는 진부분집합(strict)임에 주의.
스케줄 분류 종합 다이어그램
직렬가능성(정확성 축)과 복구가능성(장애 복구 축)은 서로 직교(orthogonal)하는 별개의 축이다. 한 스케줄은 두 축의 위치를 독립적으로 가진다.
축 1 · 직렬가능성 (정확성)
Serial ⊊ Conflict-serializable ⊊ View-serializable ⊊ (모든 serializable 스케줄).
축 2 · 복구가능성 (장애 복구)
Strict ⊊ Cascadeless ⊊ Recoverable ⊊ (모든 스케줄). 다음 절에서 상세히.
직렬가능하지만 복구 불가능한 스케줄도, 복구 가능하지만 직렬가능하지 않은 스케줄도 존재한다. 실무 DBMS는 두 축을 모두 만족시켜야 한다 — 동시성 제어(직렬가능성) + 복구 관리(복구가능성).
17.11 복구가능성·연쇄롤백 심화 (Recovery Hierarchy) 보충
§17.8에서 다룬 recoverable / cascadeless를 strict까지 3단계 위계로 확장하고, 왜 DBMS가 strict를 선호하는지를 본다.
1 Recoverable (가장 약함)
Tⱼ가 Tᵢ가 쓴 데이터를 읽었다면, Tᵢ의 commit이 Tⱼ의 commit보다 먼저.
// recoverable (단, cascade 발생) T8: W(A) T9: R(A) // 미커밋 값 읽음 T8: commit T9: commit // T8 이후 → OK
2 Cascadeless (연쇄롤백 없음)
Tⱼ는 Tᵢ가 commit한 뒤에만 Tᵢ가 쓴 값을 읽는다(Tᵢ commit이 Tⱼ read보다 먼저). 미커밋 값을 절대 안 읽으므로 연쇄 롤백 불가능.
// cascadeless T8: W(A) T8: commit T9: R(A) // 커밋된 값만 읽음 T9: commit
3 Strict (가장 강함)
Tᵢ가 쓴 데이터 항목은 Tᵢ가 commit/abort할 때까지 다른 TX가 read도 write도 못함. 미커밋 데이터에 대한 모든 접근을 차단한다.
// strict: W(A) 후 T8 종료까지 // 다른 TX는 A를 R/W 불가 T8: W(A) T8: commit // 이제부터 A 접근 허용 T9: R(A) / W(A)
위계는 강함 → 약함 순으로 strict ⊊ cascadeless ⊊ recoverable. 더 강한 조건일수록 허용하는 스케줄이 적다. Recoverable=commit 순서만 강제(연쇄롤백은 허용). Cascadeless=미커밋 값 읽기 금지(연쇄롤백 차단). Strict=미커밋 값 읽기·쓰기 모두 금지.
위계 포함 다이어그램
왜 DBMS는 strict를 선호하는가
- 복구가 단순하다. abort 시 그 TX가 쓴 값은 아무도 보지 못했으므로, before-image(이전 값)로 즉시 undo하면 끝 — 다른 TX 갱신을 추적·연쇄 롤백할 필요가 없다.
- cascade 없음. cascadeless가 보장되므로 한 TX 실패가 다른 TX 롤백을 유발하지 않는다.
- before-image 덮어쓰기 안전. 미커밋 write는 다른 TX가 안 읽으므로, 로그 기반 undo가 항상 올바른 복원값을 갖는다.
- 대가: 항목을 commit까지 잠가 두므로 동시성은 다소 낮아진다. 대부분 상용 DBMS는 strict 2PL로 이 성질을 얻는다(Ch18).
17.12 실무 격리 수준과 이상현상 심화 (Anomalies in Practice) 보충
§17.9의 4×4 표를 구체 스케줄로 한 단계 더 파고, lost update·snapshot isolation·실제 DBMS 기본값을 본다.
이상 현상별 구체 스케줄
Dirty Read (미커밋 값 읽기)
T1: W(X) // X=100→200 (미커밋) T2: R(X) // 200을 읽음 (dirty) T1: abort // X 200은 존재한 적 없음 T2: ... 200 기반 결정 → 오염
Read committed 이상에서 차단.
Non-repeatable Read (재읽기 불일치)
T1: R(X) // X=100 T2: W(X), commit // X=150 T1: R(X) // 같은 행, 150 (달라짐!)
같은 point query 두 번 결과 상이. Repeatable read 이상에서 차단.
Phantom Read (유령 행)
T1: SELECT count(*) WHERE age>30 // 5 T2: INSERT (age=40), commit T1: SELECT count(*) WHERE age>30 // 6!
같은 range query에 새 행 등장. tuple-lock으로 미삽입 행은 못 잠근다. Serializable(또는 범위 잠금)에서 차단.
Serialization Anomaly
// 각각은 commit됐지만 어떤 // 직렬 순서와도 결과 불일치 T1: R(A), W(B) T2: R(B), W(A) // T1→T2도 T2→T1도 결과와 안 맞음
선행 그래프에 cycle(T1↔T2). Serializable에서만 차단.
T1: R(X)=100 ; T2: R(X)=100 ; T1: W(X=120), commit ; T2: W(X=110), commit. 두 TX가 모두 stale한 100을 읽고 각자 갱신해 T1의 +20이 덮어써져 사라진다. (이는 본 장 §17.4 Schedule 4의 lost update와 같은 현상이다.) Read committed에서도 발생할 수 있어, 명시적 잠금(SELECT … FOR UPDATE)이나 더 높은 격리가 필요하다.
Snapshot Isolation 과 Write Skew 보충
Snapshot Isolation (SI) — forward reference
각 트랜잭션이 시작 시점의 일관된 스냅샷을 읽고, write는 자신의 버전에만 한다(MVCC). 읽기는 쓰기를 막지 않아 동시성이 높고, dirty/non-repeatable/phantom read를 대부분 막는다.
⤳ 자세한 메커니즘(버전·가시성·first-committer-wins)은 Ch18 동시성 제어에서 다룬다.
Write Skew — 격리수준 표의 한계
두 TX가 겹치지 않는 항목을 쓰지만 같은 불변식을 함께 위반하는 현상. 예: 의사 2명이 "최소 1명 당직" 규칙 아래 각자 자기 당직을 동시에 취소 → 둘 다 스냅샷상 "상대가 당직"이라 보고 commit → 0명 당직.
SI는 4가지 표준 anomaly를 막아도 write skew는 막지 못한다 — 그래서 §17.9 4×4 표(dirty/non-repeatable/phantom/serialization)만으로는 SI를 분류할 수 없다. Serializable Snapshot Isolation(SSI)이 이를 해결(Ch18).
실제 DBMS 기본 격리 수준
| DBMS | 기본 격리 수준 | 비고 |
|---|---|---|
| PostgreSQL | Read Committed | SERIALIZABLE 요청 시 SSI로 구현(write skew까지 방지). REPEATABLE READ는 사실상 SI. |
| MySQL (InnoDB) | Repeatable Read | next-key lock으로 phantom을 상당 부분 방지(표준 RR보다 강함). |
| Oracle | Read Committed | SERIALIZABLE은 실제로는 Snapshot Isolation으로 구현(엄밀한 직렬가능성 아님 → write skew 가능). |
| SQL Server | Read Committed | 옵션으로 RCSI(스냅샷 기반 read committed)·SNAPSHOT 격리 지원. |
| SQL 표준 | Serializable | 표준이 규정하는 기본값이지만 실제 제품 기본값은 대부분 더 약함. |
SQL 표준의 격리 수준 정의는 "막아야 할 anomaly" 목록으로 되어 있어, 같은 이름이라도 제품마다 구현·강도가 다르다. 특히 여러 제품의 "SERIALIZABLE"이 실제로는 Snapshot Isolation이라 write skew가 통과할 수 있다는 점이 실무의 함정이다. 정확한 직렬가능성이 필요하면 제품이 그것을 진짜로 보장하는지 확인해야 한다.
17.13 핵심 정리 (Exam Cheatsheet)
시험 직전 한 번 더. 정의와 판정 규칙 위주로.
| 주제 | 꼭 기억할 것 | 핵심도 |
|---|---|---|
| ACID | A=All or Nothing · C=일관성 보존 · I=Serializability · D=장애 후에도 유지. | 🎯 핵심 |
| 트랜잭션 상태 | active → partially committed → committed (정상). active/partially → failed → aborted. | 🎯 핵심 |
| Schedule | 모든 명령 포함, TX 내부 순서 보존, 마지막=Commit/Abort. | 🎯 핵심 |
| Conflict | 같은 Q & ≥1 write. R-R만 비충돌, R-W·W-R·W-W 충돌. | 🎯 최빈출 |
| Precedence Graph | 먼저 접근한 Tᵢ→Tⱼ. conflict serializable ⟺ acyclic, topo sort=직렬화 순서. | 🎯 최빈출 |
| View Serializable | 3조건(initial read·read-from·final write). conflict⊆view, 판정 NP-complete, blind write. | 보충 |
| Recoverable | Tⱼ가 Tᵢ 데이터 읽으면 Tᵢ commit 먼저. cascadeless ⊆ recoverable. | 🎯 핵심 |
| 격리 수준 | RU<RC<RR<Serializable. 4×4 표 외우기(RR도 phantom 허용). | 🎯 최빈출 |
| 이론 증명 직관 | 충돌=강제 순서=간선. acyclic→위상정렬=동치 serial, cycle→모순. view 판정 NP-complete, conflict⊊view⊊serializable. | 보충 |
| 복구 위계 | strict⊊cascadeless⊊recoverable. DBMS는 strict 선호(before-image로 즉시 undo, cascade 없음). | 보충 |
| 실무 격리 | lost update·write skew는 표 밖. SI는 4표준 anomaly만 차단. PG=RC, MySQL=RR, Oracle SERIALIZABLE=SI. | 보충 |
이 장은 "무엇이 올바른가(serializability)"를 정의했다. Ch18은 그것을 어떻게 강제할지를 다룬다: Locking(S/X 락), Timestamps(read/write TS), Multiple versions(MVCC).