Skip to content

Commit 585ff86

Browse files
committed
Update DB Post " [DB] 트랜잭션 격리 수준 "
1 parent 924ac0a commit 585ff86

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed

_posts/2023-02-20-DB-Transaction-Isolation-Level.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,19 +165,27 @@ author: devFancy
165165

166166
> REPEATABLE READ의 스냅샷 동작 원리
167167
168-
![]()
168+
![](/assets/img/db/DB-Concurrency-Issue-Scenario.png)
169169

170-
시나리오 분석:
170+
시나리오 분석: 아래 타임라인을 통해 두 트랜잭션이 어떻게 상호작용하는지 자세히 살펴보자.
171171

172-
1. 스냅샷 생성: 트랜잭션 B가 처음 잔액을 조회(`SELECT`)하는 순간, InnoDB는 해당 시점의 데이터 복사본, 즉 **스냅샷**을 만듭니다. 이 스냅샷에는 잔액이 `10,000원`으로 기록된다.
173-
2. 데이터 변경: 트랜잭션 A가 먼저 Lock을 얻어 결제를 처리하고, 실제 DB의 잔액을 `5,000원`으로 변경 후 커밋한다.
174-
3. 스냅샷 참조: 트랜잭션 B는 A의 커밋 이후 로직을 재개하지만, DB의 최신 데이터를 보지 않고 **자신이 만들어 둔 스냅샷을 계속 참조한**다. 따라서 B에게 잔액은 여전히 `10,000원` 이다.
175-
4. 업데이트 실패: 결국 B는 `UPDATE ... WHERE balance = 10000` 쿼리를 실행하게 되고, 실제 DB 값(5,000원)과 달라 업데이트는 실패한다.
172+
* T1: 트랜잭션 A(5,000원 결제)와 B(3,000원 결제)가 거의 동시에 시작된다. 트랜잭션 B는 잔액 `10,000원`을 조회하고, 이 시점에 **B를 위한 데이터 스냅샷(Snapshot)이 생성된다.**
173+
174+
* T2 ~ T3: 트랜잭션 A가 먼저 DB Lock을 획득하여 결제를 처리한다. 트랜잭션 B는 동일한 데이터에 접근하려다 Lock을 얻지 못하고 **대기(Blocked) 상태**가 된다.
175+
176+
* T4: 트랜잭션 A가 처리를 마치고 `5,000원`이 차감된 잔액을 **커밋(Commit)**한다. DB의 실제 잔액은 `5,000원`이 되고 Lock은 해제된다. 대기하던 트랜잭션 B가 드디어 Lock을 획득하고 깨어난다.
177+
178+
* T5: 로직을 재개한 트랜잭션 B가 비즈니스 로직을 위해 잔액을 참조한다. 이때 B는 DB의 최신 값(5,000원)을 보는 것이 아니라, **T1에서 생성한 자신만의 스냅샷**을 일관되게 참조한다. 따라서 B에게 잔액은 여전히 `10,000원`으로 보인다. 이것이 바로 `REPEATABLE READ`의 핵심 동작이다.
179+
180+
* T6 ~ T7: 트랜잭션 B는 10,000원을 기준으로 3,000원 결제를 처리한 후, `UPDATE ... WHERE balance = 10000` 쿼리를 실행한다. 하지만 T4 시점에 A가 커밋한 DB의 실제 잔액은 5,000원이므로 `WHERE` 조건이 불일치하여 **최종 업데이트는 실패**한다.
176181

177182
이처럼 `REPEATABLE READ`**'트랜잭션 내의 일관성'** 을 위해 **'데이터의 최신성'** 을 희생하는 전략을 사용한다.
178183

179184
이 특징을 이해해야 동시성 이슈가 발생했을 때 정확한 원인을 파악하고 `READ COMMITTED`와 같은 다른 격리 수준을 대안으로 고려할 수 있다.
180185

186+
이처럼 `REPEATABLE READ`는 트랜잭션의 일관성을 보장하기 위해 **자신이 시작된 이후에 커밋된 변경 사항은 반영하지 않는다.**
187+
188+
이 특징을 이해해야 동시성 이슈가 발생했을 때 정확한 원인을 파악하고 `READ COMMITTED`와 같은 다른 격리 수준을 대안으로 고려할 수 있다.
181189

182190
### SERIALIZABLE
183191

163 KB
Loading

0 commit comments

Comments
 (0)