Isolation anomaly map

격리 수준은 표준 표와 DBMS 구현을 분리해서 읽는다

READ COMMITTED, REPEATABLE READ 같은 이름은 같아도 MVCC 스냅샷, 잠금 읽기, 충돌 실패 방식에 따라 실제 동작이 달라진다. 그래서 먼저 표준 이상 현상을 보고, 그다음 제품별 구현과 UPDATE 패턴을 확인한다.

이상 현상 RU RC RR SER Dirty 허용 커밋 전 값 노출 방지 커밋 값만 읽음 방지 스냅샷/잠금 방지 직렬 결과 Non-repeatable 허용 다시 읽으면 값 변경 가능 문장별 스냅샷 방지 트랜잭션 관찰 안정 방지 직렬 순서 유지 Phantom 허용 새 행이 보일 수 있음 가능 범위 재조회 차이 제품별 MVCC/next-key 차이 방지 직렬화 보장
RU에서 SER로 갈수록 표준 이상 현상은 줄어든다. RR의 Phantom은 DBMS 구현에 따라 체감이 달라진다. Lost update는 표와 별도로 UPDATE 패턴을 검사한다.
Read Uncommitted Read Committed Repeatable Read Serializable
표준 이상 Dirty, Non-repeatable, Phantom을 먼저 막힘 정도로 읽는다.
구현 차이 MVCC와 잠금 방식 때문에 같은 이름도 제품별 체감이 달라진다.
갱신 분실 read-modify-write 흐름은 표와 별도로 쿼리 패턴을 검사한다.

표준 표는 “무엇을 막는가”를 빠르게 보는 기준이다

SQL isolation levels
READ UNCOMMITTED 미커밋 값을 읽을 수 있는 가장 낮은 수준
Dirty허용 가능
Non-repeatable허용 가능
Phantom허용 가능

존재하지 않을 수도 있는 값을 읽으므로 일반 업무에는 거의 피한다.

READ COMMITTED 각 문장이 시작될 때 커밋된 데이터만 읽는다
Dirty방지
Non-repeatable가능
Phantom가능

웹 트랜잭션 기본값으로 흔하지만, 재조회 일관성은 보장하지 않는다.

REPEATABLE READ 같은 트랜잭션 안의 읽기 관찰을 안정화한다
Dirty방지
Non-repeatable방지 목표
Phantom제품별 차이

스냅샷이 직렬 실행과 항상 같은 뜻은 아니므로 write skew를 확인한다.

SERIALIZABLE 성공한 결과가 어떤 직렬 순서와 같도록 만든다
Dirty방지
Non-repeatable방지
Phantom방지

정확성은 강하지만 대기, abort, serialization failure 재시도가 필요하다.

같은 이름이라도 구현 방식이 실제 체감을 바꾼다

MVCC / lock / SSI
PostgreSQL RR 트랜잭션 스냅샷으로 일반 SELECT 결과를 안정화한다

PostgreSQL의 REPEATABLE READ는 snapshot isolation에 가깝다. 팬텀처럼 보이는 일반 SELECT 변화는 줄지만, 모든 직렬화 이상을 막으려면 SERIALIZABLE을 검토한다.

MySQL InnoDB consistent read와 locking read를 구분해야 한다

일반 SELECT는 스냅샷을 보고, SELECT ... FOR UPDATE나 범위 UPDATE는 next-key lock으로 새 행 진입을 막을 수 있다.

Lost update는 이상 현상 표와 분리해서 UPDATE 패턴으로 판단한다

read -> compute -> write is the risky shape
위험한 모양: 앱 read-modify-write

SELECT balance로 읽고 애플리케이션에서 계산한 뒤 UPDATE balance = 새값처럼 절대값을 저장하면 다른 트랜잭션의 변경을 덮을 수 있다.

별도 판단
보호 원자적 UPDATE

SET balance = balance + 10처럼 DB 안에서 계산한다.

보호 SELECT ... FOR UPDATE

읽은 행을 잠그고 갱신을 직렬화한다.

감지 version 조건

WHERE id=? AND version=?로 충돌을 감지하고 재시도한다.