핵심 포인트

MVCC도 같은 행의 쓰기 충돌은 막지 못합니다. 대신 읽기만 이전 버전으로 우회합니다.

핵심은 하나입니다. 같은 행 A를 두 트랜잭션이 동시에 바꾸려 하면 순서를 정해야 하므로 잠금이 필요하고, MVCC의 이점은 그동안 SELECT가 멈추지 않는다는 데 있습니다.

공통 전제: 행 A에는 한 번에 하나의 쓰기만 확정
이전 커밋 버전 다른 읽기는 이 시점을 기준으로 볼 수 있음
T1이 새 값 작성 중 X-Lock을 잡은 동안 다른 쓰기는 대기

쓰기 충돌은 MVCC여도 직렬화

변하지 않음
T1: UPDATE A SET val = 100 T2: UPDATE A SET val = 200
1
T1이 행 A의 X-Lock을 먼저 획득

새 버전을 만들고 있지만 아직 확정된 값은 아닙니다.

2
T2의 UPDATE는 같은 행이라 대기

MVCC도 쓰기-쓰기 충돌 자체를 제거하지는 못합니다.

3
T1이 끝난 뒤에만 다음 쓰기가 진행

같은 행의 최종 순서는 잠금 해제 시점으로 정해집니다.

차이는 기다리는 동안의 읽기 처리

읽기만 달라짐
T3: SELECT val FROM A
잠금 기반 읽기
T1이 끝날 때까지 SELECT도 함께 멈춤

쓰기가 잡은 잠금 때문에 조회 동시성도 함께 낮아집니다.

MVCC 읽기
이전 커밋 버전을 즉시 반환

쓰기 중인 값 대신 snapshot을 읽으므로 조회는 계속 진행됩니다.

정리: MVCC의 장점은 쓰기 충돌 제거가 아니라, 쓰기 중에도 읽기를 계속 살려 두는 것입니다.