PE Notes · DB
동시성제어 (병행제어)
다수 트랜잭션의 직렬성을 지키면서 처리량을 유지하는 잠금·2PL·데드락 처리와 MVCC·OCC를 비교합니다.
같은 행을 여러 트랜잭션이 동시에 만지면 한쪽 갱신이 사라지고, 아직 커밋되지 않은 값을 읽거나, 범위 조회가 왔다 갔다 합니다. 는 그 간섭을 막으면서도 직렬 실행만큼 기다리게 하지 않는 장치입니다.
목표와 분류
은 동시에 돌린 결과가, 어떤 한 줄 순서의 직렬 실행과 같다는 뜻입니다. 정확성의 기준입니다.
| 문제 | 현상 |
|---|---|
| 갱신 손실 | 두 쓰기가 겹쳐 한쪽이 사라짐 |
| 더티 리드 | 미커밋 값을 읽음 |
| 팬텀 리드 | 범위 결과가 중간에 바뀜 |
비관적은 충돌이 잦다고 보고 잠급니다. 낙관적은 드물다고 보고 버전()이나 커밋 검증()을 씁니다.
잠금과 2PL
공유 잠금(S)은 읽기끼리 같이 잡을 수 있고, 배타 잠금(X)은 읽기·쓰기 모두를 막습니다.
| 보유 \ 요청 | S | X |
|---|---|---|
| S | 허용 | 대기 |
| X | 대기 | 대기 |
은 잠금을 얻기만 하는 성장 단계와, 풀기만 하는 수축 단계로 나눕니다. 중간에 섞이면 직렬성이 깨집니다. Strict 2PL은 배타 잠금을 종료까지 쥐어 더티 리드를 막습니다. 대가는 입니다.
Wait-for Graph에서 사이클이면 데드락입니다. 비용이 작은 쪽을 롤백하거나, 오래 기다리면 타임아웃합니다. 예방은 오래된 트랜잭션만 기다리게 하거나(Wait-Die), 오래된 쪽이 새 쪽을 끊는 방식(Wound-Wait)입니다. 계좌 이체처럼 자원을 항상 같은 순서로 잠그는 것도 현장 처방입니다.
MVCC와 OCC
MVCC는 읽기가 이전 커밋 버전을, 쓰기가 새 버전을 만듭니다. 읽기-쓰기가 서로를 막지 않습니다. 버전 정리(Vacuum) 비용이 따릅니다. OCC는 잠금 없이 읽고 로컬에서 고친 뒤, 커밋 직전에만 충돌을 봅니다. 충돌이면 처음부터 다시입니다.
| 축 | 2PL | MVCC | OCC |
|---|---|---|---|
| 가정 | 비관 | 버전으로 읽기 보호 | 낙관 |
| 읽기-쓰기 | S-X 충돌 | 없음 | 없음 |
| 데드락 | 가능 | 없음 | 없음 |
| 적합 | 쓰기 경합 | 읽기 많음 | 충돌이 드묾 |
좌석 중복은 SELECT FOR UPDATE, 조회수 +1은 원자적 UPDATE, 이체 데드락은 낮은 번호부터 잠그는 식으로 기법과 업무를 붙입니다.