Computer >> 컴퓨터 >  >> 프로그래밍 >> MySQL

DBMS 잠금(Lock) 기반 동시성 제어 완벽 정리: 2단계 잠금 프로토콜부터 엄격·엄중 프로토콜까지

잠금(Lock)은 DBMS에서 동시성 제어(Concurrency Control)를 유지하는 데 필수적인 핵심 요소입니다. 잠금 기반 동시성 제어 방식을 채택한 시스템에서는 트랜잭션이 필요한 잠금을 획득하기 전까지는 어떤 데이터도 읽거나 쓸 수 없습니다.

잠금의 두 가지 유형

잠금 기반 프로토콜에는 크게 두 가지 유형의 잠금이 사용됩니다.

  • 이진 잠금(Binary Lock) — 잠김(locked)과 잠기지 않음(unlocked) 단 두 가지 상태만 가질 수 있는 가장 단순한 형태의 잠금입니다.
  • 공유/배타 잠금(Shared/Exclusive Lock) — 공유 잠금(Shared Lock)은 읽기 연산만 수행할 때 획득하며, 데이터를 변경하지 않으므로 여러 트랜잭션이 동시에 함께 보유할 수 있습니다. 반면 배타 잠금(Exclusive Lock)은 쓰기 연산을 수행할 때 사용되며, 해당 배타 잠금을 보유한 트랜잭션만 데이터 값을 변경할 수 있습니다.

대표적인 잠금 프로토콜로는 다음 네 가지가 있습니다.

1. 단순 잠금 프로토콜(Simplistic Lock Protocol)

트랜잭션은 쓰기 연산을 수행하기 전에 데이터 값에 대한 잠금을 획득하고, 쓰기 연산이 끝난 직후 잠금을 해제합니다. 아래는 단순 잠금 프로토콜의 실행 예입니다.

T1T2
R(A)
R(A)
Lock(B)
R(B)
W(B)
Unlock(B)
Lock(C)
R(C)
W(C)
Unlock(C)
Commit
Commit

위 예제에는 T1과 T2 두 개의 트랜잭션이 있습니다. 읽기 연산에는 별도의 잠금이 필요 없으며, 각 트랜잭션은 쓰기 연산 직전에 잠금을 획득하고 쓰기가 완료되면 바로 해제합니다.

2. 2단계 잠금 프로토콜(Two-Phase Locking Protocol)

2단계 잠금 프로토콜은 성장 단계(Growing Phase)축소 단계(Shrinking Phase), 두 개의 단계로 구성됩니다. 트랜잭션은 성장 단계에 있을 때만 새로운 잠금을 획득할 수 있고, 축소 단계에 진입하면 이전에 획득한 잠금을 해제할 수는 있지만 더 이상 새로운 잠금을 얻을 수 없습니다. 배타 잠금은 X로, 공유 잠금은 S로 표기합니다. 아래는 2단계 잠금 프로토콜의 실행 예입니다.

T1T2
S(A)
R(A)
S(A)
R(A)
X(B)
R(B)
W(B)
X(C)
R(C)
W(C)
Unlock(C)
Unlock(A)
Unlock(B)
Unlock(A)
Commit
Commit

위 예제에서 T1과 T2는 변수 A에 대해 읽기 연산만 수행하므로 공유 잠금(S)을 통해 A를 함께 공유합니다. T1은 B에 대한 쓰기를 위해 배타 잠금(X)을 획득한 뒤 곧바로 해제하며, T2도 C에 대해 같은 방식으로 처리합니다.

3. 엄격 2단계 잠금 프로토콜(Strict Two-Phase Locking Protocol)

엄격 2단계 잠금 프로토콜은 일반 2단계 잠금 프로토콜과 거의 유사하지만, 한 가지 중요한 차이점이 있습니다. 엄격 2PL에서는 트랜잭션이 획득한 모든 배타 잠금을 커밋(commit) 또는 롤백(abort)될 때까지 계속 보유해야 합니다. 아래는 엄격 2단계 잠금 프로토콜의 실행 예입니다.

T1T2
S(A)
R(A)
S(A)
R(A)
X(B)
R(B)
W(B)
X(C)
R(C)
W(C)
Unlock(A)
Unlock(A)
Commit
Unlock(B)
Commit
Unlock(C)

위 예제에서 T1과 T2는 읽기 연산만 수행하는 변수 A를 공유 잠금으로 공유합니다. T1은 B에 대한 쓰기를 위해 배타 잠금을 획득하고, T2도 C에 대해 동일하게 처리합니다. 핵심은 배타 잠금이 트랜잭션이 커밋된 이후에야 해제된다는 점이며, 공유 잠금에는 이러한 제약이 적용되지 않습니다.

4. 엄중 2단계 잠금 프로토콜(Rigorous Two-Phase Locking Protocol)

엄중 2단계 잠금 프로토콜은 2단계 잠금 프로토콜과 엄격 2단계 잠금 프로토콜의 확장 형태입니다. 이 프로토콜에서는 트랜잭션이 보유한 모든 잠금(공유 잠금과 배타 잠금 모두)을 커밋 또는 롤백 시점까지 유지합니다. 아래는 엄중 2단계 잠금 프로토콜의 실행 예입니다.

T1T2
S(A)
R(A)
S(A)
R(A)
X(B)
R(B)
W(B)
X(C)
R(C)
W(C)
Commit
Unlock(A)
Unlock(B)
Commit
Unlock(A)
Unlock(C)

위 예제에서 T1과 T2는 읽기 연산만 수행하는 변수 A를 공유 잠금으로 공유하며, T1은 B에 대한 쓰기를 위해 배타 잠금을, T2는 C에 대해 동일하게 배타 잠금을 획득합니다. 엄중 프로토콜에서는 공유 잠금과 배타 잠금 모두 트랜잭션이 커밋된 후에야 해제됩니다.