CS/💾 DB

💾 Concurrency control의 기초, 트랜잭션 ( 2 )

늦은산책 2024. 4. 23. 09:55
해당 내용은 쉬운코드님의 영상을 기반으로 제작되었습니다

이전 블로그에서 트랜잭션의 4개 특성 중 Isolation 이 굉장히 중요하다는 것과 까다로운 것을 알 수 있었다.

https://latewalk.tistory.com/230

 

💾 Transaction, 트랜잭션이란?

해당 내용은 쉬운코드님의 영상을 기반으로 제작되었습니다 🔌 트랜잭션이란? 단일한 논리적인 작업의 단위 여러개의 SQL문들을 단일 작업으로 묶어 나눠질 수 없게 만든 것 transaction의 SQL문들

latewalk.tistory.com

 

정말 간단히 알아본 Isolation에서 좀 더 깊게 알아보는 시간을 가져보자

🔌 예시 상세 설명

이전 시간에 간단하게 작성한 예시를 상세하게 설명해보자

상황1. J가 H에게 20만원을 이체하려고 한다 (transaction1)
상황2. H가 본인에게 30만원을 입금하려고 한다. (transaction2)
근데 중요한 것은 J가 20만원을 이체하고 H에게 입금되기 전에 H가 자신에게 입금을 한 것이다.

이걸 트랙잭션 관점에서 보면 첫번째 J가 입금을 하는 트랜잭션은 현재 H의 통장의 잔액이 100만원으로 읽었다. 하지만 중간에 H가 자신에게 입금을 하는 transaction으로 인해 H의 통장 잔액이 130만원으로 바뀌어버린 것이였다.

서로의 상태를 공유하지 않는 트랜잭션은 그대로 진행이 되었고 100만원으로 인식하고 20만원을 넣은 J에 의해 H의 통장은 130만원이 아닌 100에서 20을 더한 120만원으로 업데이트되며 트랜잭션이 마무리 되면서 통장 잔액은 130만원이 아닌 120만원으로 변경되었다.

 

실행방법 1.

  • 트랜잭션을 분리하여 20만원을 먼저 넣게 만들고 commit 하게 하여 30만원을 넣는 트랜잭션을 가동한다.

실행방법 2.

  • 30만원을 입금하는 트랜잭션을 실행하고 commit 한 후에 20만원을 넣는 트랜잭션을 실행한다.

실행방법 3.

  • 20만원을 이체하는 트랜잭션을 실행하는데 갑자기 30만원을 넣는 트랜잭션이 실행된다면 20만원 트랜잭션을 멈추고 기다렸다가 30만원 트랜잭션이 commit 되면 20만원을 넣는 트랜잭션이 commit 이 된 후 데이터를 읽고 이체를 하는 방법이 있다.

 


 

🔌 Schedule

스케쥴링을 하는 것은 위에 적은 실행 방법을 그려보는데 있다. 한 개의 방법마다 실행되는 쿼리마다 opration이라고 생각하면 밑에 보이는 것 처럼 순서가 나올 수 있다. (4번째는 우리가 예기에 적힌 상황을 적은것이다.)

 

이것을 Schedule이라고 부른다.

  • 여러 tracsaction들이 동시에 실행 될 때 각 transaction에 속한 operation들의 실행 순서를 적은 것
  • 각각 transaction 내의 operations 들의 순서는 방법이 달라져도 바뀌지 않는다는 것도 중요하다.

 

1. Serial Schedule (1, 2)

  • 한번에 하나의 transaction이 실행되는 schedule을 의미한다.
  • 성능
    • 한번에 하나의 transaction만 실행되면서 좋은 성능은 낼 수 없다. 한 개의 일을 끝마치는 동안 IO작업을 놀게 하기 때문에 현실적으로 사용할 수 없다.

2. Nonserial Schedule (3, 4)

  • transaction이 겹쳐서 실행되는 것을 의미한다.
  • 성능
    • IO작업이 쉬지 않고 진행되기 때문에 transaction들이 겹쳐서 실행이 된다. 때문에 IO작업의 효율성이 높아지고 동시성 또한 높아지면서 같은 시간동안 더 많은 transaction을 처리 할 수 있다.
    • 하지만 transaction들이 어떤 형태로 겹쳐서 실행되는지에 따라 이상한 결과(예시처럼)를 초래할 수 있다.

 


 

Nonserial Schedule을 사용하고 싶은데 이상한 결과로 안나오게 하고 싶어!
그럼 serial schedule과 동일한 nonserial schedule을 찾자!




🔌 Conflict serializable

serial schedule 과 conflict equivalent 일때 conflict serializable하다

Schedule의 동일화

♪ Conflict

  • 서로 다른 transaction 소속
  • 같은 데이터에 접근
  • 최소 하나는 write operation 이여야 한다.

 

예를 들어 3번 스케쥴을 보면 2개의 operation이 같은 데이터를 사용하고 w가 한번이라도 사용된 곳이 3곳 정도 보인다. 이는 모두 Confilct 하다라고 말할 수 있다. 이러한 Conflict 는 순서가 바뀌면 결과가 바뀐다

 

♪ Conflict equivalent

  • 두 schedule은 같은 transaction들을 가진다
  • 어떠한 conflicting operations의 순서도 양쪽 schedule 모두 동일하다.
    • 어떤 nonserial 스케쥴의 conflict 의 순서가 같은 transaction 을 다루는 serial 스케쥴의 conflict 순서와 같아야 한다.

♪ 결과

  • 그렇다면 serial schedule 중 하나인 2번과 nonserial schedule인 3번이 conflict equivalent하기 때문에 3번은 conflict serializable하다 라고 할 수 있는 것이다
  • 번외 : 4번은 어떠한 serial schedule 중에도 Conflict equivalent하지 않기 때문에 conflict serializable하지 않다.

 


 

🔌 Unrecoverable schedule, Recoverable Schedule

♪ Unrecoverable Schedule

스케줄을 하나 더 예상해보자 이를 스케줄 5번 이라고 한다면

  1. J가 20만원을 이체하는 트랜잭션1이 실행되고 이후에 H가 자신에게 30만원을 입금하는 트랜잭션2가 실행된다
  2. 여기서 트랜잭션2안에서 트랜잭션1이 같이 진행을 하는 것이다. 그렇다면 트랜잭션 2 내부에서 30만원 입금이 끝나고 그 내용을 read해서 변경을 하는것으로 마무리가 된다
  3. 하지만 트랜잭션2에서 어떠한 문제가 발생해 rollback이 되었다면 H의 계좌가 원 상태로 돌아가는데 이때 J의 트랜잭션1은 commit 이 되면서 계좌는 여전히 20만원이 빠진 상태로 들어가는 것이다.

이렇게 rollback을 해도 두 사람이 이전 상태로 회복되는 것이 불가능 할 수 있기 때문에 이런 schedule을 DBMS가 허용하면 안되는 것이다. 그래서 이런 위험하지 않은 Recoverable한 스케줄을 만들어야 한다

 

Recoverable Schedule

위에 예시를 연결해서 설명을 해보자면 각자의 트랜잭션을 따로 놓고 보았기 때문에 트랜잭션1은 트랜잭션2의 상태와 관계없이 commit 이 된 것을 알 수 있다. 하지만 트랜잭션2번이 끝나고 상태를 확인한 후에 그 상태에 따라 맞춰서 commit 혹은 rollback하는 것이다

 

즉, schedule 내에서 그 어떤 tracsaction도 자신이 읽은 데이터를 write 한 transaction이 먼저 commit/rollback 전까지는 commit하지 않는 경우가 recoverable schedule 이라고 하는 것이다

 

● cascading rollback

위처럼 recoverable 한 스케줄에서 만약 트랜잭션2가 rollback을 하게되면 해당 상황을 보고 트랜잭션1도 rollback을 하게 되는데 이를 cascading rollback이라고 한다. 이는 rollback이 계속해서 발생하여 비용이 많이 발생한다

 

● cascadeless schedule 

비용이 많이 발생하는 것을 막고자 이제 트랜잭션을 다시 분리하게 된다. 트랜잭션2가 종료가 되면 그 값을 읽어와서 트랜잭션1을 처리하게 되는것이다. 

 

schedule 내에서 어떤 transaction도 commit 되지 않은 transaction들이 write한 데이터는 읽지 않는 경우를 cascadeless schedule 이라고 한다

 

● strict schedule

cascadeless 한 스케줄은 과연 안정적일까?

1번 트랜잭션이 만약 실패한다면 2번 트랜잭션의 결과도 사라지게 될 것이다. 이는 casecadeless 하지만 데이터 자체가 완전히 rollback이 되면서 오히려 문제가 발생하는 것이다.

그래서 casecadeless 한 스케줄의 조건에 쓰지도 않는 이라는 조건을 하나 더 붙이게 된다

 

schedule 내에서 어떤 transaction도 commit 되지 않은 transaction들이 write한 데이터는 읽지도 쓰지도 않는 경우를 strict schedule 이라고 한다

 

이렇게 되면 각 트랜잭션이 분리된다.

 

🔌 결과

동시성 제어는 serializability 와 recoverability를 제공하고 이와 관련된 트랜잭션의 특성이 Isolation이다