Two-Phase Locking, Strict 2 Phase Lock

서버란·2024년 10월 14일

CS 지식

목록 보기
25/25

1. Two-Phase Locking (2PL, 2단계 잠금 규약)

Two-Phase Locking(2PL)은 트랜잭션이 데이터를 읽고 쓰기 위해 잠금(lock)을 설정할 때 두 가지 단계로 나뉩니다. 이 방식은 트랜잭션이 잠금을 설정하는 "확장 단계"와 잠금을 해제하는 "축소 단계"로 구분됩니다. 중요한 점은 트랜잭션이 잠금을 해제하기 전까지는 자유롭게 잠금을 설정할 수 있지만, 잠금을 한 번 해제하기 시작하면 더 이상 잠금을 설정할 수 없다는 규칙입니다.

2PL의 단계:
1. 확장 단계(Growing Phase): 트랜잭션이 필요한 데이터에 대해 잠금을 설정할 수 있습니다. 이 단계에서는 새로운 잠금을 자유롭게 설정할 수 있습니다.

  1. 축소 단계(Shrinking Phase): 트랜잭션이 잠금을 해제하는 단계입니다. 이 단계에서 트랜잭션은 잠금을 해제할 수 있지만, 한 번 해제하면 더 이상 잠금을 추가로 설정할 수 없습니다.

이 규칙에 의해, 2PL은 충돌 직렬 가능성(Conflict Serializable)을 보장하여 여러 트랜잭션이 동시에 실행될 때 데이터 무결성을 유지할 수 있습니다.

2PL 예시:
다음은 트랜잭션 T1과 T2가 2PL 규약을 따르는 예시입니다.

  • 트랜잭션 T1: 계좌 A에서 100을 출금하고, 계좌 B에 100을 입금
  • 트랜잭션 T2: 계좌 A의 잔액을 조회
  1. T1: 계좌 A에 배타 잠금(Exclusive Lock)을 설정하고, A에서 100을 출금
  2. T2: 계좌 A에 접근하려 하지만, T1이 잠금을 걸고 있어서 대기 상태
  3. T1: 계좌 B에 배타 잠금을 설정하고, B에 100을 입금
  4. T1: 작업 완료 후, 계좌 A와 B의 잠금을 해제 (축소 단계 시작)
  5. T2: 이제 계좌 A에 접근하여 잔액을 조회 가능

여기서 2PL은 T1이 먼저 잠금을 설정하고 해제할 때까지, T2가 A에 접근할 수 없게 함으로써 충돌을 방지합니다.

2. Strict Two-Phase Locking (Strict 2PL)

Strict Two-Phase Locking(Strict 2PL)은 2PL의 특수한 경우로, 더 엄격한 규칙을 따릅니다. Strict 2PL에서는 쓰기 잠금(Exclusive Lock)을 트랜잭션이 완료될 때까지(Commit 또는 Rollback) 해제하지 않습니다. 즉, 쓰기 작업이 끝났다고 해서 잠금을 바로 해제하지 않고, 트랜잭션이 완전히 커밋되기 전까지 잠금을 유지합니다.

이 방식은 Dirty Read(커밋되지 않은 데이터를 읽는 문제)와 Lost Update(갱신 손실)를 방지하는 데 효과적입니다.

Strict 2PL의 단계:
1. 확장 단계(Growing Phase): 트랜잭션이 잠금을 설정하는 단계입니다. 트랜잭션은 읽기 잠금(Shared Lock)쓰기 잠금(Exclusive Lock)을 설정할 수 있습니다.

  1. 축소 단계(Shrinking Phase): 읽기 잠금은 트랜잭션이 읽기 작업을 마친 후 해제할 수 있지만, 쓰기 잠금은 트랜잭션이 커밋될 때까지 유지됩니다.

Strict 2PL에서는 쓰기 작업을 완료했더라도, 트랜잭션이 끝나기 전까지는 다른 트랜잭션이 해당 데이터를 읽을 수 없게 만듭니다.

Strict 2PL 예시:
같은 예시에서 Strict 2PL을 적용해보겠습니다.

1.T1: 계좌 A에 배타 잠금(Exclusive Lock)을 설정하고, A에서 100을 출금
2. T2: 계좌 A의 잔액을 조회하려 하지만, Strict 2PL 규칙에 의해 A의 쓰기 잠금이 트랜잭션이 커밋될 때까지 유지되므로, T2는 대기 상태
3. T1: 계좌 B에 배타 잠금을 설정하고, B에 100을 입금
4. T1: 트랜잭션 완료 후, 커밋 시점에 계좌 A와 B의 잠금을 해제
5. T2: 이제 계좌 A에 접근하여 잔액을 조회 가능

여기서 Strict 2PL은 T1이 계좌 A와 B에 대해 쓰기 작업을 마친 후에도 커밋되기 전까지 잠금을 유지하여, T2가 커밋되지 않은 데이터를 읽는 것을 방지합니다. 이는 Dirty Read를 방지하는 역할을 합니다.

3. 2PL과 Strict 2PL의 차이점

구분2단계 잠금 규약(2PL)Strict 2단계 잠금 규약(Strict 2PL)
잠금 해제 시점읽기 및 쓰기 잠금을 트랜잭션의 실행 중에 해제할 수 있음쓰기 잠금은 트랜잭션이 커밋 또는 롤백될 때까지 유지
Dirty Read 방지방지하지 않음. 다른 트랜잭션이 커밋되지 않은 데이터를 읽을 수 있음Dirty Read를 방지. 트랜잭션이 완료되기 전까지 쓰기 작업이 완료된 데이터는 다른 트랜잭션이 읽을 수 없음
갱신 손실(Lost Update)트랜잭션이 작업 중에 잠금을 해제할 수 있어 갱신 손실이 발생할 가능성이 있음갱신 손실 방지. 트랜잭션이 완료되기 전까지 다른 트랜잭션이 동일 데이터를 수정할 수 없도록 배타 잠금을 유지
복잡도단순. 기본적인 충돌 직렬 가능성을 보장하는 잠금 기법조금 더 엄격한 규칙을 적용하여, 동시성 제어에 있어 더 강력한 무결성 보장

4. 왜 Strict 2PL을 사용할까?

Strict 2PL은 데이터 무결성을 더욱 강력하게 보장하기 위해 사용됩니다. 다음과 같은 이유 때문에 Strict 2PL이 필요할 수 있습니다:

  1. 더티 리드 방지(Dirty Read Prevention): Strict 2PL은 트랜잭션이 커밋되기 전까지 쓰기 잠금을 유지하기 때문에, 다른 트랜잭션이 커밋되지 않은 데이터를 읽는 문제를 방지할 수 있습니다.
  2. 갱신 손실 방지(Lost Update Prevention): 트랜잭션이 완료되기 전까지 다른 트랜잭션이 같은 데이터를 수정할 수 없게 하므로, 갱신 손실 문제를 방지합니다.
  3. 더 강력한 일관성 보장: Strict 2PL은 트랜잭션이 완료되기 전까지 모든 쓰기 잠금을 유지하기 때문에, 데이터의 일관성을 더 엄격하게 보장합니다.

하지만 Strict 2PL은 동시성 성능에 더 많은 제약을 가합니다. 트랜잭션이 완료될 때까지 쓰기 잠금을 해제하지 않기 때문에 다른 트랜잭션들이 더 오래 대기해야 할 수 있습니다. 따라서 동시성 성능과 데이터 무결성 사이의 트레이드오프를 고려하여 사용하는 것이 좋습니다.


Q1: 2PL과 Strict 2PL의 성능 차이는 어떤 상황에서 크게 나타날까요?

2PL과 Strict 2PL의 성능 차이는 트랜잭션의 쓰기 작업이 얼마나 자주 발생하고, 트랜잭션의 길이에 따라 크게 달라집니다.

  1. 트랜잭션의 빈번한 쓰기 작업:
  • Strict 2PL에서는 쓰기 잠금을 트랜잭션이 완료될 때까지 유지하기 때문에, 다른 트랜잭션이 해당 데이터를 사용하려면 대기해야 합니다. 만약 쓰기 작업이 많은 트랜잭션들이 동시에 발생하면, 대기 시간이 길어져 성능이 저하될 수 있습니다.
  • 반면 2PL은 쓰기 작업이 끝나면 잠금을 바로 해제할 수 있어 대기 시간이 줄어들어 동시성 성능이 더 좋아질 수 있습니다.
  1. 트랜잭션의 길이:
  • 긴 트랜잭션은 Strict 2PL에서 성능에 큰 영향을 미칠 수 있습니다. 긴 트랜잭션이 여러 데이터에 대해 쓰기 작업을 하고, 트랜잭션이 커밋될 때까지 쓰기 잠금을 유지하면, 다른 트랜잭션들이 오랫동안 대기해야 할 수 있습니다.
  • 반면, 2PL은 중간에 잠금을 해제할 수 있기 때문에 동시성 성능이 더 나은 경우가 많습니다.

결론적으로, Strict 2PL은 트랜잭션이 짧거나 쓰기 작업이 적을 때 성능 저하가 크지 않지만, 긴 트랜잭션이나 쓰기가 자주 발생하는 환경에서는 성능 차이가 크게 나타날 수 있습니다.

Q2: Strict 2PL을 사용할 때 발생할 수 있는 교착 상태(Deadlock) 문제는 어떻게 해결할 수 있을까요?

Strict 2PL은 교착 상태(Deadlock)가 발생할 가능성을 높입니다. 이는 트랜잭션이 완료될 때까지 쓰기 잠금을 오래 유지하기 때문입니다. 교착 상태는 두 트랜잭션이 서로 잠금을 기다리면서 무한 대기 상태에 빠지는 상황을 말합니다. 이를 해결하는 방법은 여러 가지가 있습니다:

  1. 타임아웃(Timeout):
  • 트랜잭션이 잠금을 얻기 위해 기다리는 시간을 설정하여, 일정 시간이 지나면 트랜잭션을 자동으로 롤백하는 방법입니다. 이 방법은 간단하지만 효과적으로 교착 상태를 방지할 수 있습니다. 하지만 타임아웃 시간이 너무 짧으면 불필요한 롤백이 자주 발생할 수 있습니다.
  1. 교착 상태 탐지(Deadlock Detection):
  • 트랜잭션 간의 잠금 대기 그래프를 생성하고, 사이클이 발생하는지 확인하여 교착 상태를 탐지합니다. 교착 상태가 발생하면, 트랜잭션 중 하나를 강제로 롤백시켜 교착 상태를 해결합니다.
  • 이 방법은 교착 상태를 탐지하는 데 약간의 오버헤드가 있지만, 시스템 성능에 미치는 영향은 크지 않습니다.
  1. 교착 상태 예방(Deadlock Prevention):
  • 자원을 잠그는 순서를 일정하게 유지하여 교착 상태를 사전에 방지할 수 있습니다. 예를 들어, 트랜잭션이 데이터를 잠글 때 항상 같은 순서로 잠금을 걸도록 규칙을 설정하면 교착 상태를 예방할 수 있습니다.
  • 하지만 자원을 고정된 순서로 잠그는 것은 유연성이 떨어질 수 있습니다.

Strict 2PL에서는 이러한 방법들을 적용하여 교착 상태를 해결하거나 예방할 수 있으며, 특히 타임아웃과 탐지 알고리즘이 많이 사용됩니다.

Q3: Strict 2PL이 갱신 손실과 더티 리드를 방지하는 것 외에 다른 동시성 제어 기법과 비교하여 가지는 장점은 무엇일까요?

Strict 2PL은 갱신 손실(Lost Update)더티 리드(Dirty Read)를 방지하는 것 외에도 다음과 같은 중요한 장점들을 제공합니다:

  1. 간단하고 널리 사용됨:
  • Strict 2PL은 구현이 상대적으로 간단하고, 충돌 직렬 가능성을 쉽게 보장하기 때문에 많은 데이터베이스 시스템에서 기본적인 동시성 제어 기법으로 사용됩니다. 널리 사용되는 만큼 잘 검증된 방법이기도 합니다.
  1. 강력한 일관성 보장:
  • Strict 2PL은 트랜잭션이 완료될 때까지 쓰기 잠금을 유지하기 때문에, 여러 트랜잭션이 동시에 데이터를 읽고 쓸 때도 데이터 일관성을 더 강력하게 보장할 수 있습니다. 이는 트랜잭션의 순서가 중요할 때 특히 유용합니다.
  1. 갱신 손실을 완전히 방지:
  • Strict 2PL에서는 트랜잭션이 완료되기 전까지 다른 트랜잭션이 데이터를 수정할 수 없기 때문에, 갱신 손실이 완벽하게 방지됩니다. 다른 동시성 제어 기법은 이 문제를 부분적으로만 해결할 수 있지만, Strict 2PL은 완전히 방지합니다.
  1. 충돌 직렬 가능성 보장:
  • Strict 2PL은 충돌 직렬 가능성(Conflict Serializable)을 보장합니다. 이는 여러 트랜잭션이 동시에 실행될 때, 직렬로 실행된 것과 동일한 결과를 보장한다는 의미입니다. 이로 인해 데이터 무결성을 확실히 유지할 수 있습니다.
  1. 예측 가능성:
  • Strict 2PL의 동작 방식은 매우 예측 가능합니다. 트랜잭션이 커밋될 때까지 다른 트랜잭션이 데이터를 수정하거나 읽을 수 없다는 것은 애플리케이션 개발자에게 데이터의 일관성에 대한 확실성을 제공합니다. 이는 복잡한 트랜잭션 로직을 다루는 애플리케이션에서 유리합니다.

결론적으로, Strict 2PL은 다른 동시성 제어 기법에 비해 더 강력한 일관성 보장을 제공하며, 데이터 무결성을 유지해야 하는 환경에서 매우 유용한 기법입니다. 다만, 이로 인해 동시성 성능이 저하될 수 있다는 단점도 고려해야 합니다.

profile
백엔드에서 서버엔지니어가 된 사람

0개의 댓글