Study/DB

동시성 제어

Gyuri 2021. 8. 22. 19:49

동시성 제어의 필요성

동시 실행되는 트랜잭션들은 각각에 정의된 명령들이 끼어들기 방식으로 실행되는데, 이런 끼어들기 방식에 의해 실행되는 순서를 스케줄 이라고 함. 트랜잭션의 스케줄은 전적으로 운영체제의 권한이고, 사용자는 어떤 스케줄로 트랜잭션들이 실행되는지 미리 예측 거의 불가능.

 

  • 갱신 분실 : update 결과가 흔적도 없이 사라짐. 갱신 분실이 발생하는 원인은 두 트랜잭션이 같은 값을 읽고 독립적인 연산을 한 후 서로 간의 연산 결과에 관계없이 그 결과를 독립적으로 저장했기 때문
  • 연쇄 복귀 : 트랜잭션 연산 성공적으로 끝났는데도 다른 트랜잭션 때문에 실패한 상황. 만약, T3과 T4 실행중에, T3이 예기치 못한 상황에 의해 실패해 처음 상태로 복귀하게 된다면, T3의 x값은 이전의 값으로 돌아간다. 하지만 T4는 이미 T3의 잘못된 값을 읽고 연산을 수행했으므로 T4 또한 복귀해야함. 그런데 이 상항에서 만약 T3이 복귀하기 전에 T4가 이미 완료를 했다면, 이 때 T4의 복귀는 불가능함. 트랜잭션의 지속성 특성에 의해 한 번 완료됐으면 더 이상 복귀 불가능하기 때문!                                                                                                                  * 연쇄 복귀가 일어나는 이유는 완료되지 않은 트랜잭션의 쓰기 연산에 의해 갱신된 데이터를 다른 트랜잭션이 읽었기 때문이 경우 하나의 트랜잭셔닝 복귀 했을 때다른 트랜잭션도 연달아 복귀해야하는 연쇄 복귀 상황이 발생할 수 있고 경우에 따라 이미 완료된 트랜잭션까지 복귀해야하는 심각한 상황 초래 가능
  • 불일치 분석 : 끼어들기에 의해 트랜잭션의 일관성이 유지되지 못하는 상황

 

갱신 분실, 연쇄 복기, 불일치 분석 등의 문제가 발생한 이유 : 다중프로그래밍 환경에서 하나의 트랜잭션 실행 중 다른 트랜잭션이 끼어들어 실행했기 때문!

 

 

직렬 스케줄 : 각 트랜잭션들의 연산이 끼어들기 방식이 아닌 순차적으로 실행되는 스케줄

=> 시스템 성능을 향상시킬 수 있는 다중 프로그래밍의 장점 포기하게 됨

 

직렬 가능한 스케줄 : 직렬 스케줄과 실행 결과가 동일한 스케줄 (병행 수행 최대한 보장하며 직렬 스케줄로 실행한 것과 동일한 결과 얻음)

*직렬 가능 스케줄인지 알 수 있는 법 : 스케줄에 나타난 연산들의 순서를 전체적인 실행 결과에 영향 미치지 않도록 바꿨는데, 이 때 주어진 스케줄이 직렬 스케줄로 변환되면 직렬 가능한 스케줄!

 

C1, C2의 실행 순서를 서로 바꿔도 전체적인 결과에 영향 없는지 어떻게?

1) C1과 C2가 서로 다른 데이터 항목에 대한 연산일 경우 교환 가능. 예로, C1과 C2가 각각 write(x), write(y)면 서로 다른 데이터에 대한 연산이므로 연산자의 종류에 관계 없이 두 연산의 순서를 바꿔도 전체적인 결과에 영향 미치지 않음

2) C1과 C2가 같은 데이터 항목에 대한 연산일 경우는 연산자 종류에 따라 다름.

C1과 C2가 모두 read 연산일 경우에 교환 가능 : 순서 바꿔도 결과에 영향 없음

C1과 C2에 하나라도 write 연산이면 교환 불가능

 

 

 

끼어들기 허용하는 운영체제 환경에서 실행되는 모든 스케줄이 직렬 가능한 스케줄이 되도록 제어하는 방법 => 병행 수행으로 인한 문제들이 발생되지 않으면서, 동시에 병행성도 보장 받게됨!

=> 잠금(locking) 과 타임스탬프(timestamp)

 

 

  • 잠금 : 트랜잭션의 실행 순서 강제로 제어해 직렬 가능한 스케줄 되도록 보장하는 것
  • 타임스탬프 : 트랜잭션들의 실행 순서를 제어하기보단 최대한 병행 수행을 보장하다가 직렬 가능한 스케줄에 위배될 가능성 있으면 트랜잭션의 실행 취소하는 방법

 

잠금 : 하나의 트랜잭션이 실행하는 동안 특정 데이터 항목에 대해 다른 트랜잭션이 동시에 접근하지 못하게 독점하는 기법. 잠금 걸린 데이터는 잠금을 실행한 트랜잭션만 독점적으로 접근할 수 있고 다른 트랜잭션으로부터 간섭/방해를 받지 않는 것이 보장됨 잠금 걸린 데이터는 잠금을 수행한 트랜잭션만이 해제 가능

=> lock, unlock 연산 사용!

 

 

하나의 트랜잭션이 특정 데이터 항목에 대해 잠금 설정했을 때 다른 트랜잭션이 그 데이터를 무조건 접근할 수 없으면 지나치게 제한적인 경우 있음. 예로, 두 개 이상의 트랜잭션이 동일한 데이터에 대해 동시에 읽기 연산을 실행한다 해도 결과에는 영향 X. BUT, 두 개의 트랜잭션이 동시에 하나의 데이터 항목에 대해 write(x)연산 요구하면 한 트랜잭션의 갱신 정보가 다른 트랜잭션에 영향 미칠 수 있으므로 동시에 접근하는 것 막아야함.

 

  • S-lock(x) : 공유잠금(shared lock) 트랜잭션 T가 데이터 항목 x에 대해 S-lock(x)를 걸면, T는 x에 대해 read(x) 연산은 가능하지만 write(x)연산은 불가능
  • X-lock(x) : 배타잠금. 트랜잭션 T가 데이터 항목 x에 대해 X-lock(x)를 걸면, T는 x에 대해 read(x) 연산, write(x)연산 모두 가능

즉, S-lock(x) 간에는 동시 잠금 허용. S-lock(x)과 X-lock(x), X-lock(x)과 X-lock(x) 간에는 서로 간의 동시 잠금 허용 X

 

 

 

트랜잭션의 잠금 설정 규칙

  1. 트랜잭션은 데이터 항목 x에 대해 read(x)연산을 실행하기 전에 S-lock(x)나 X-lock(x)를 실행해야함
  2. 트랜잭션은 데이터 항목 x에 대해 write(x)연산을 실행하기 전에 X-lock(x)를 실행해야함
  3. 트랜잭션은 데이터 항목 x에 대해 read(x)나 write(x)연산의 실행이 끝나면 unlock(x) 실행해야함
  4. 트랜잭션은 데이터 항목 x에 대해 S-lock(x)나 X-lock(x)를 실행한 경우에만 unlock(x) 실행 가능

 

잠금 & 직렬 가능한 스케줄

잠금 규칙은 직렬 가능한 스케줄의 최소한의 조건임. 단순한 잠금 설정만으로 직렬 가능한 스케줄이 보장되는 건 X

 

만약, T14와 T15 둘 다 대기 상태에 들어가게 되면 어느 것도 더 이상 진행하지 못함 => ‘교착상태

교착상태에 빠지면 외부에서 강제적으로 트랜잭션을 중단하거나 잠금 해제하지 않는 이상 영원히 대기상태!

 

 

읽기/쓰기 연산 전후에 잠금/해제 설정하는 것만으론 동시성 문제 해결 못하기때문에 잠금 연산을 정해진 절차에 의해 설정해야함 => ’2단계 잠금 규약 (2PL)’

2PL : 직렬 가능한 스케줄을 보장하는 방법. 각 트랜잭션의 lock과 unlock 연산을 정해진 절차에 의해 설정하도록 함. 2PL은 직렬 가능한 스케줄의 충분 조건(보장해줌). 필요 충분 조건은 아님!

 

  • 확장 단계(growing phase) : 트랜잭션이 lock연산은 수행할 수 있으나 unlock 연산은 수행 불가
  • 축소 단계(shrinking phase) : 트랜잭션이 unlock 연산은 수행할 수 있으나 lock 연산은 수행 불가

=> 모든 lock연산이 unlock 연산보다 앞서 실행돼야하는 것이 2단계 잠금 규약의 핵심! 트랜잭션은 확장 단계로 시작해 축소 단계로 끝난다.

 

모든 트랜잭션이 2단계 잠금 규약을 지키면, 이들로부터 생성될 수 있는 모든 가능한 스케줄은 직렬 가능한 스케줄이 됨. BUT, 2단계 잠금 규약이 직렬 가능한 스케줄을 생성하기 위한 필요 충분조건은 아님!

즉, 2단계 잠금 규약은 직렬 가능한 스케줄을 보장하지만이 규약이 지켜지지 않는다해서 직렬 가능한 스케줄을 아예 생성하지 못하는 건 아님!

 

 

단순 2단계 잠금 규약만으로 교착 상태와 연쇄 복귀 문제 해결 불가 => ‘엄격한 2단계 잠금 규약’

  • 교착 상태 : 각 트랜잭션 시작 전에 모든 필요한 잠금을 동시에 설정. 그렇게 되면 하나의 잠금 설정 후에 다른 잠금을 기다릴 필요 없어 교착 상태 빠질 일 없음
  • 연쇄 복귀 : 모든 X-lock에 대한 unlock 연산을 트랜잭션이 완료된 후에 실행. 이렇게 되면 완료되지 않은 트랜잭션에 의해 갱신된 데이터를 다른 트랜잭션이 읽거나 쓸 가능성 없음.

잠금 단위 : 잠금의 대상이 되는 데이터 객체의 크기 (보통 ‘레코드’ 단위로 락을 걺! 때때로 테이블)

* 잠금 단위가 너무 크면(예 : 테이블) 동시성 수준이 낮아지지만 테이블 하나에만 잠금 설정 필요하므로 제어기법이 간단해짐 (관리 쉬움)

* 잠금 단위가 너무 작으면 동시성 수준은 높아지지만 관리가 복잡해짐

'Study > DB' 카테고리의 다른 글

오라클에서의 트랜잭션  (0) 2021.08.22
복구  (0) 2021.08.22
트랜잭션  (0) 2021.08.22
무결성과 보안  (0) 2021.08.22
오라클 실습  (0) 2021.08.22