컴퓨터(Computer Science)/데이터베이스, DB, DataBase

데이터베이스, 트랜잭션(Transaction) -2(동시성 제어)

게임이 더 좋아 2020. 12. 14. 18:00
반응형
728x170

저번 글에서

상태 전이도를 보면서

트랜잭션에 대해서 동시성 제어를 해야한다고 말했다. 그것부터 이어서 가보자

 


 

동시성 제어(Concurrency Control)

동시성 제어는 꼭 필요하다. 컴퓨터 프로그래밍에서 무엇을 배웠든 간에 빠지지 않고 등장하는 주제 중 하나다.

 

혼자 사용하면 거의  필요 없지만 항상 다중 사용자 DBMS를 염두에 두고 설계한다.(왜? 돈벌어야지 ㅎ)

-> 하나의 트랜잭션이 완료되지 않은 상태에서 다른 트랜잭션이 실행 가능??

트랜잭션 간의 간섭이 발생하여 일관성이 깨지면 안되니까 제어를 하는 것이다. 바로 그것이 동시성 제어.

 


무슨 연산이길래 서로 간섭을 한다는 것일까??? 알아보자

 

역시나 읽고 쓰는 문제다. ㅎㅎ 내가 다 읽기 전에 누가 내용을 바꿔 써버리면 잘못읽게 되니까? 

 

  • read(x)

-이름이 x인 데이터베이스 항목을 트랜잭션의 지역변수 x로 읽어들이는 것이다.

-> SQL의 SELECT 연산과 같다.

 

  • write(x)

-지역변수 x 에 저장된 값을 데이터베이스 항목 x에 저장한다.

-> SQL의 UPDATE 연산과 같다.

 

**x는 테이블, 레코드 또는 필드와 같이 데이터베이스를 구성하는 임의의 구성 요소가 된다.

 

++write(x) 연산 수행 시,  수행하자마자 그 결과가 디스크에 꼭 저장되는 것은 아님

-> 대부분 주기억장치 buffer를 유지해 나중에 블록(block) 단위로 입력한다.

 

 

 


 

흠... 구체적으로 어떻게 동시성 제어가 일어난다는 건데?? 라는 물음을 가질 수 있다.

 

동시성 제어라는 것은 다시 말해서 트랜잭션 명령들 간의 끼어들기(Interleave)가 가능하다는 얘기다.

끼어들어도 잘 돌아간다는 얘기다.

어떻게 그럴 수 있느냐?? -> 스케줄(Schedule) 이놈 때문이다.

** 스케줄은 운영체제 고유의 권한으로 어떻게 실행되는지 알 수는 없지만 잘 돌아간다는게 핵심이다.

 


 

그렇다면 그 핵심에 대해서 잘못되었을 경우를 알아보자

 

3가지가 있다.

  • 갱신 분실(lost update)

-T1, T2가 같은 값을 읽었음에도 독립적인 연산을 해서 연산 결과에 상관없이 그 결과를 독립적으로 저장했기 때문이다.

T1의 연산 결과가 사라져버렸다.

200이 된다.

 

  • 연쇄 복귀(cascading rollback)

-완료되지 않는 트랜잭션의 쓰기 연산(T3의 write)에 의해 갱신된 데이터를

-다른 트랜잭션이 읽어서(T4의 read) 연쇄 복귀가 발생한다.

-> 즉 하나의 트랜잭션의 복귀 시 다른 트랜잭션까지 연달아 복귀를 해야 하는 경우가 있고

이런 경우 이미 완료된 트랜잭션까지 복귀해야만 하는 심각한 상황을 초래할 수 있다.(지속성 위배)

 

  • 불일치 분석(inconsistent analysis)

-끼어들기로 인해 트랜잭션의 일관성이 깨지는 경우

 

 


 

그렇구나 이런 일이 생기는구나.. 그러면 그걸 스케줄로 해결한다고 했는데 어떻게??

 

1. 트랜잭션들을 순차적으로 실행(끼어들기 X)

-트랜잭션이 수행되는 중간에 다른 트랜잭션의 연산을 막음

 

2. 끼어들기( 병렬 수행)을 최대한 허용하면서 직렬 스케줄(Serial schedulte)과 같이 실행 순서 제어

-직렬 가능한 스케줄

 

위와 같다 더 자세히 알아보자.

(당연히 끼어들기 안되는 방법은 알아볼 필요도 없고)

 


 

결국 다중 프로그래밍으로 인한 간섭이 생겨서 동시성 제어를 하고 이를 스케줄로 해결한다고 했다.

그 중 직렬 가능한 스케줄에 대해서 알아보자.

 

-직렬 스케줄

 

-직렬 가능한 스케줄(Serializable Schedule)

이건 또 뭔가 싶다. 직렬 스케줄이랑 다른게 뭐지? 

-> 직렬 스케줄과 실행 결과가 동일한 스케줄을 말한다.

 

직렬 가능한 스케줄인지 판단하는 방법 또한 존재하는데

-스케줄에 나타난 연산들의 순서를 전체적인 실행 결과에 영향을 미치지 않도록 교환한다.

-이 때 주어진 스케줄이 직렬 스케줄로 변환되면 직렬 가능한 스케줄이다.

 

예를 보고 넘어가자

 

-> 직렬 스케줄로 변환하면??

 

 

만약 변환이 안된다면 왜 안될까??

 


 

직렬 스케줄? 만약 이렇게 안되면?

안되는 것도 될 때까지 할 수 있다. 그런 방법도 존재한다.

 

바로

1. 잠금(locking) // 트랜잭션의 실행 순서를 강제로 제어하는 방법

2. 타임스탬프(timestamp) // 최대한 병행 수행을 보장하면서 직렬 가능한 스케줄에 위배될 가능성이 생기면 실행 취소

 

**대부분의 DBMS에서는 잠금 기법을 사용함.

 


 

동시성 제어의 마지막 잠금에 대해서 알아보자

 

잠금이란?

하나의 트랜잭션이 수행하는 동안 특정 데이터 항목에 대해 다른 트랜잭션이 동시에 접근하지 못하도록 방지

잠금이 걸린 데이터는 잠금을 실행한 트랜잭션만 독점적으로 접근가능

-> 여기서 Critical section과 Mutex가 생각났으면 고수 ㅎ

 

잠금의 기능은 뭐 잠그는 것과 해제하는 거겠지?

lock, unlock이 있다.

 

 


잠금의 종류에는 2가지가 있다.

1. 공유잠금(Shared lock : S-lock)

-트랜잭션 T가 데이터 항목 x에 대해 S-lock을 걸면 T는 read(x) 연산은 가능하지만 write(x)는 불가능

결국 하나의 데이터 항목에 대해 여러 개의 공유 잠금이 가능하다. (읽기만 가능하대)

 

2. 배타잠금(Exclusive lock : X-lock)

-트랜잭션 T가 데이터 항목 x에 대해 X-lock을 걸면 T는 read(x), write(x) 연산 모두 가능하다.

결국 하나의 데이터 항목에 대해 하나의 배타잠금만 가능하다 (쓰기도 가능하니까 여러 개의 잠금 불가능)

 

그렇다면 공유 잠금, 배타 잠금 병행이 가능한가?????

-> ㅎㅎ 안되넹 

위의 규칙에 의하면 안된다.

T11을 보면 어떻게 잠그는지 저렇게 알 수 있다.

 

 

** 이 잠금은 무엇을 위한 것 이라그랬지??

바로 직렬 가능한 스케줄을 위함이라 그랬지?? 

하지만 이 잠금을 쓴다고 해서 보장하는 것은 아니다.

과연 아래 트랜잭션이 잠금이 되었다고 바로 직렬 가능해질까??

 

 


 

여기 좌측부터 A, B, C 트랜잭션들의 묶음이 있다. 과연 어느 것이 직렬가능할까??

답은 밑에..있다

 

 

 

 

 

A, B 가능 X

C 가능

 

 

뭐 C가 가능하다고 그랬다. 그럼 어떻게든 잠금으로 직렬스케줄을 만들 수 있느냐?? 

아무렇게나 한다고 해서 되는 것도 아니다.

이러한 일들이 왜 벌어지느냐? 바로 교착상태(deadlock)이 발생가능하기 때문이다.

 

??? 보기엔 잘되는 것 같지??

아니다. ㅎㅎ

 

 

아... 잠금해도 안되네 포기해야겠다..

가 아니라 그래서

 

2단계 잠금 규약(2-Phase Locking protocol : 2PL)이라는 것이 등장했다.

다음 단락에서 알아보자

 


 

2단계 잠금 규약이란

잠금을 2 단계로 나누어서 수행한다는 얘기다.( 이 방법은 직렬 가능한 스케줄을 보장한다-대부분의 DBMS 사용가능)

 

++ 모든 직렬 가능한 스케줄들이 2PL을 준수하는 것은 아니고 2PL은 그저 직렬 가능한 스케줄의 충분조건일 뿐이다.

 

 

?? 뭐이리 간단해 이걸로 진짜 가능해?? 라는 질문이 나올 수 있다.

 

왜 그런 것이 가능하냐?? 

2가지 단계로 가능하다.

 

1. 확장 단계(growing phase)

- 트랜잭션이 lock연산은 수행가능 unlock 연산은 수행불가능 단계

 

2. 축소 단계(shrinking phase)

- 트랜잭션이 unlock연산은 수행가능 lock 연산은 수행불가능 단계

 

 

 

**트랜잭션은 확장단계로 시작하여 축소단계로 끝나는 순서다. 

 

 


다시 문제를 내보겠다. ㅎㅎ 과연 무엇이 직렬가능인지 맞춰보자

A,B순서로 있다.

 

 

정답은

A 직렬 가능

B 불가능

 


 

하지만 2PL이 장점만 있다면 다들 이것만 썼겠지 항상 반대급부가 있기마련..

**교착상태 방지가 불가능하다

 

** 연쇄복귀 문제가 발생한다.

 

 

 


 

 

아.., 이것도 문제가 많네..? 어떻게 해야하지??라고 할 때

불현듯 스치는 생각이 있었으니.

 

모든 데이터를 잠궈버리면 그런 에러가 나니까..? 진짜 필요한 데이터만 잠궈버리자!! 

 

그렇게 잠금 단위(Locking Granularity)가 나오게 되었다.

 

잠금 단위

-잠금의 대상이 되는 데이터 객체의 크기를 말함

-예) 필드, 레코드, 디스크 블록, 테이블, 데이터베이스 등 구성요소가 된다.

 

-> 잠금 단위가 커질수록

동시성 수준 낮아짐, 트랜잭션 제어 간소화

 

->잠금 단위가 작아질수록

동시성 수준 높아짐, 트랜잭션 제어 복잡화

 

이를 필요에 따라 혼용으로 해결

 

와!! 동시성은 결국 필요한 것만 잠궈야 하는구나!! 로 해결했다..

 

다음 글에서는 시스템 장애와 그 장애에 대한 복구를 알아보자

 

 

 

 

반응형
그리드형