트랜잭션 격리(Isolation) (2)

jYur·2022년 11월 24일
0

(1편에서)
아까는 변경 중인 걸 읽었을 때 문제가 발생했고 커밋된 것만 읽도록 해서 해결했지.
그런데, 읽는 도중에 읽었던 데이터가 다른 트랜잭션에 의해 변경(커밋까지)되는 상황은 어떨까?


2. Read Committed

2.1. 발생 문제 예시

트랜잭션 A는 전씨와 김씨의 계좌 잔액을 읽으려고 해

트랜잭션 A가 시작되었을 때 전씨와 김씨의 계좌 잔액은 둘 다 1,000원이었어

  1. 그런데 트랜잭션 A가 전씨의 잔액(1,000원)을 읽었을 때
    (김씨의 잔액을 읽기 전)
SELECT *
FROM account
WHERE owner = '전씨'
  1. 트랜잭션 B가 송금한다고
    전씨의 계좌 잔액에서 500원을 빼고
    김씨의 계좌 잔액에 500원을 더하고
UPDATE account
SET balance = 500
WHERE owner = '전씨'
UPDATE account
SET balance = 1500
WHERE owner = '김씨'

커밋까지 해버렸네?
(전씨 잔액: 500원, 김씨 잔액: 1,500원)

  1. 이제 A가 김씨의 잔액을 읽었어. 1500원.
SELECT *
FROM account
WHERE owner = '김씨'

결과적으로, A가 읽은 데이터는
전씨 잔액: 1,000원, 김씨 잔액: 1,500원

? ... 돈 500원을 복사했어!

트랜잭션 A만 단독으로 실행했다면 잔액 총합이 2,000원이었을 텐데, 트랜잭션 B가 끼어들면서 2,500원이 된 거지.

해결

트랜잭션 A가 읽는 동안 데이터가 변하지 않게 하면 좋겠지.
그렇다고 트랜잭션 B를 A가 끝날 때까지 기다리게 하는 건 좋지 않을 거야.

다시 말해, 중간에 B가 난입해서 A가 읽고 있는 데이터를 변경하더라도 A에게 영향을 미치지 않도록 해야겠지.

Multi-Version으로 분리하는 방법을 쓴대.
; A는 A대로 시작했을 때의 데이터(버전1)을 가지고 읽고, B는 B대로 변경하고 커밋해서 데이터(버전2)를 만드는 거야. 그럼 A가 읽은 데이터가 비록 최신 버전의 데이터는 아니겠지만 돈이 복사되거나 사라지거나 하진 않겠지.
; 격리 수준을 Repeatable Read로 높이는 거야.


🤔

근데 사실 방금 언급한 상황이 실무에서 일어날까 의문이 들기도 하네.
되도록 쿼리 개수를 줄이는 게 좋으니까 아래처럼

SELECT * FROM account
WHERE owner = '전씨' OR owner = '김씨'

이런 식으로 많이 쓰는 것 같아서. 그럼 끼어들 틈이 없잖아?


지금까지는 주로 쓰기와 읽기의 대결이었다면
(쓰고 있는데 읽거나)
(쓰고 있는데 쓰거나)
(읽고 있는데 쓰거나)

읽고 쓰기 vs 읽고 쓰기는 어떨까?

(3편에서 계속..)

0개의 댓글