본문 바로가기

CS 과목(CS科目)/데이터 베이스(データベース)

15. concurrency control(Serial schedule, NonSerial schedule) - Part1

이번 concurrency 부분은 난이도가 있는 부분이므로, 시간을 들여서 공부를 하자!

위 예제에 대한 트랜잭션 작성에는 아래와 같이 3가지 case가 있다.

case1

 

case2

 

case3

 

잘못된 트랜잭션

case1~3의 트랜잭션의 실행의 결과는 우리가 원한 답이 나온다.

그러나, case 4의 경우, 최종적으로 우리가 원한 답이 나오지를 않는다.(이 이유에 대해서는 지난 번에 설명을 했으므로 여

기서는 설명을 하지 않겠다.) 

case4와 같이 transaction2의 업데이트 결과가 반영되지 않아서 최종 업데이트된 값(Transaction1의 최종값)이 원하는 값이 나오지 않는 오류, 이러한 오류를 Lost Update 현상 이라고 부른다. 

read(), write() 등 각각의 작업을 Operation이라고 부른다. 

case4의 Operation들을 모두 간소화시켜 보자. 

 

r1(K) : Transaction1에 속한 read 함수이며, K에 대한 balance값을 읽어 들인다.

c1 : Transaction1이 완료에 대한 Commit.

-> 위 2가지의 간소화식을 이해하면 다른 간소화식들도 이해가 될 것이다. 

이 간소화식들을 아래와 같이 정렬을 할 수가 있다. 

 

 

참고로, 문서 상에서 트랜잭션의 Operation들의 실행 순서를 표시할 때는 그림의 왼쪽 부분과 같이 가로로 많이 적는다.

 

schedule(운영체제에서의 scheduling과 개념이 약간 비슷하다.)

schedule에서 기억해야 할 중요한 것이 있다.

우선 위 그림에서 빨간색 박스 안의 Operation의 실행 순서와 보란색 박스 안의 Operation의 실행 순서를 자세히 보라.

어떤 case에서는 실행의 순서가 모두 같다.

즉, 어떤 case로 실행을 하여도 Transaction1의 실행 순서는 바뀌지 않고, Transaction2의 실행 순서도 바뀌지 않는다.

-> 각 트랜잭션 내의 Operation들의 순서는 바뀌지 않는다 라는 특징을 schedule은 가지고 있다. 

 

serial schedule vs nonserial schedule

 

serial schecule의 성능 vs nonserial schedule의 성능

serial schedule의 장/단점

장점 : 각 transaction의 Operation이 겹쳐서 실행이 되지 않기에 이상한 결과값이 나오지는 않는다.

단점 : Operation이 I/O 작업을 하는 동안에 cpu가 다른 transaction의 Operation을 실행시키지 못하므로,

동시에 여러 Transaction을 실행시키지 못하기에 퍼포먼스가 매우 안 좋아서 현실적인 사용이 불가능하다. 

nonserial schedule의 장/단점

장점 : 여러 Transaction의 Operation들을 동시에 실행시킬 수 있으므로 퍼포먼스가 매우 좋다.

단점 : Transction들이 겹쳐서 실행되는 만큼 이상한 결과값을 만들어 낼 가능성이 있다. 

(위 내용은 이 시점에서는 이해가 잘 안 될 것이다. 아래의 설명을 읽고, 다시 여기로 돌아 와서 이해해보자)

1. r2(H) : 이 부분은 DB가 저장돼 있는 HDD/SDD에서 값을 읽어 오는 I/0 작업이다. CPU는 I/O 작업을 본인이 하지 않기에 

놀고 있는 상태가 된다(이 부분은 운영체제의 지식이기에 여기서 자세히 설명을 하지는 않겠다). CPU가 노는 동안 다른

Transaction의 Operation을 실행을 시키고 싶어도 위 그림에서도 알 수가 있듯이 Transaction2번의 실행이 끝이 나야

Transation1의 Operation들을 실행시킬 수 있기에 각기 다른 Transaction들의 Operation을 동시에 CPU가 실행시키지 못하

게 되어, 퍼포먼스가 매우 좋지 못하다. 

2. w2(H) : 이 부분도 1과 동일한 I/O 작업이기에 , 똑같은 원리로 퍼포먼스가 매우 좋지 못하다.

3. c2 : 이 부분이 실행되고 나서야 다른 transaction을 실행할 수가 있다.

-> serial schedult은 각기 다른 Transaction의 Operation들을 동시 실행이 안 되기에 매우 매우 속도가 느림.

그러나 각 Transcation의 Operation들이 겹쳐서 실행이 되지는 않기에 이상한 결과값이 나오지는 않는다. 

 

 

r2(H) : I/0작업이기에 CPU가 놀고 있는 것처럼 보이지만, nonserial은 다른 transaction의 Operation의 실행을 시켜도 되기

에 r2(H)의 I/O 작업 시간에 CPU는 놀지 않고,  다른 트랜잭션의 Operation인 r1(k)를 실행을 한다. 

-> nonserial은 서로 다른 transation의 Operation을 동시에 CPU가 실행가능하기에 처리 속도가 매우 빨라 매우 좋은 퍼포

먼스를 낸다.

그러나 Transaction의 Operation이 겹치므로, 이상한 결과값을 내는 가능성이 생긴다. 

여기에서 우리는 고민에 빠지지 않을 수가 없다. 

nonserial schedule을 사용하여 어떻게든 빠른 실행을 이뤄내고는 싶은데, 또 이상한 결과값을 내는 것 때문에 사용이 망설

여 진다는 고민거리이다.

이 고민거리는 우리의 개발자 선배님들도 똑같이 하여 하나의 아이디어를 냈다.

그것은 바로 serial schedule과 동일한(equivalent) nonserial schedule을 만들자 라는 아이디어이다.( 지금은 이해가 안됨. 아래를 찬찬히 정독을 하고 여기로 다시 돌아 오면 이해가 된다.ㅎㅅㅎ)

그러나 이 아이디어를 구현하기에 앞서, "schedule이 동일하다"의 의미가 무엇인지부터 정의를 할 필요가 있었다.

아래에서 그 방법을 설명하겠다.

conflict(read-write conflict, write-write conflict)

2개의 Operation에 대해 아래의 3가지 조건을 만족할 때, 그 2개의 Operation은 conflict하다 라고 말할 수가 있다.

1. 2개의Operation은 서로 다른 트랜잭션의 소속이여야 한다.

2. 2개의 Operation은 같은 데이터에 접근해야 한다. 

3. 최소 하나의 Operation이 write() Operation이여야 한다. 

 

아래에서 conflict한 2개의 Operation을 찾아 보자!! Let's Go~~~~~~~~

]

r2(H) 와 w1(H)

1. 서로 다른 트랜잭션에 소속,

2. 둘 다 H라는 같은 데이터를 취급,

3. 1개의 write()  Operation이 존재하므로, 

-> conflict한 Operation이다. 그리고 read()와 write()로 이루어진 conflict를 read-write conflict라고 부른다. 

w2(H)와 r1(H)

1. 서로 다른 트랜잭션 소속의 Operation이다.

2. H라는 같은 데이터를 취급한다.

3.  1개  write() Operation을 가진다.

-> 이것도 read-write conflict이다. 

w2(H) vs w1(H)

1.서로 다른 트랜잭션에 소속

2. H라는 같은 데이터

3. 2개의 write()

-> write-write conflict이다. 

Q. conflict 개념이 중요한 이유는 뭘까?

A. 2개의 Operation의 실행 순서가 바뀌면 결과값도 바뀌기 때문이다.( 이것도 아래 부분에 가서 설명을 듣고 다시 돌아 오자)

아래의 예시를 보자. schedule3의 어느 read-write conflict의 2개의 Opreation의 실행 순서를 뒤바꿔 보겠다.

이 2개의 Operation 이외의 Operation들은 일단 그림에서 빼겠다.

이제 2개의 Operation의 실행 순서를 바꾸어 보겠다.

r1(H)의 실행 순서를 젤 처음으로 가져오면 결과값이 230이 된다. 이는 실행 순서를 바꾸기 전의 값(200)과 다르다. 

자 이제 conflict equivalent에 대한 개념만 이해를 한다면 위에서 언급된 2가지에 대해 이해를 할수가 있게 된다.

1. serial schedule과 동일한(equivalent) nonserial schedule을 만들자

2. schedule이 동일하다

 

conflict equivalent

conflict equivalent는 2개의 schedule에 대해 정의가 되는 개념이다.

일단, 위 1,2의 조건들을 읽어도 바로 감이 오지 않을 것이니 예를 들어 먼저 설명을 하겠다.

설명에 앞서, 전제 조건을 먼저 숙지하자.

1. schedule2(Serial schedule)와 schedule3(nonserial schedule)에 대한 예시이다.

2. 이 2 schedule 에는 각각 3개의 conflict들이 존재한다.

자 이제는 진짜 설명으로 들어가겠다.

1번째 conflict
2번째 conflict

 

3번째 conflict

1,2,3번째 conflict 모두, 2개의 schedule에서 순서가 뒤바뀌지 않는다. 

고로, 

conflict equivalent의 2번째 조건은 만족하였고,

shedule2(serial schedule)나 schedule3(nonserial schedule)이나 모두 같은 트랜잭션들로 이루어 져있으므로,

schedule2,3은 서로 conflict equivalent하다.

Q 자 그럼 2개의 Schedule이 서로 conflict equivalent하다는 것은 무엇을 의미하는가??

A. [결과값이 보장되지 않는 nonserial schedule]인 schedule3의 실행의 결과값이 [결과값이 보장이 되는 serial schedule]인 shcedule2와 똑같다는 것을 의미한다.(이것의 증명에는 수학이 필요하다. 증명식을 알고 싶으신 분들은 구글링 ㄱ ㄱ)

-> 이렇게 해서

serial schedule과 동일한 nonserial schedule을 만들었고,

schedule이 동일(equivalent)해졌다.(정확히는 schedule의 결과값이 동일해졌다.)

(schedule2와4가 conflict equivalent한지 스스로 풀어 보자)

Conflict serializable

nonserial schedule인 schedule3은 이제 serial schedul인 schedule2와 동일해졌다.

serial schedule과 conflict equivalent일 때, 그 nonserial schedule을 Conflict serializable 이라고 부른다. 

 

그럼 RDBMS는 어떻게 해결책을 구현을 하는 걸까?

위 방법은 비효율적이다.

만약, 고객의 요청이 너무 많아서 실행해야 할 Transaction의 schedule이 conflict equivalent한지 안 한지를 확인하는 것은

너무나도 큰 비용이 들어 간다. 

그래서 애초에 해당 트랜잭션이 conflict equivalent한지 안 한지를 검사하는 것이 아니라

미리 해당 트랜잭션을 conflict serializable로 만들어서 실행을 한다. 

그럼 어떻게 nonserial schedule을 conflict serializable로 만들까??

그 역할을 하는 것이 다음 시간에 배울 concurrency control 이다. 

( concurrency control makes any schedules serializable )