티끌모아 태산

트랜잭션 - concurrency control 기초(2) 본문

CS 지식/데이터베이스

트랜잭션 - concurrency control 기초(2)

goldpig 2023. 12. 9. 12:44
728x90

  이번 시간에는 concurrency control 기초인 recoverbility와 트랜잭션들이 동시에 실행될 때 rollback이 발생하면 어떻게 될지 알아 보겠습니다. 

지난번에 배웠을 때 처럼 K가 H에게 20만원을 이체할 때 H도 본인 계좌에 30만원을 입금하면 여러 형태의 실행이 가능 할 수있다는 것을 확인했습니다. 그리고 각 case 마다 나다타는 operations의 순서를 우리는 schedule이라고 하였습니다. 

여러 transaction들이 동시에 실행될 때 각 transaction에 속한 operation들의 실행 순서를 Schedule 이고 합니다.

출처: 쉬운코드

  자 그럼, 저번 시간에는 serializability에 대해서 배워보았는데요 이번시간에는 recoverbility에 대해서 배워보겠습니다.

다음과 같은 상황이 있다고 해보겠습니다. 첫 번째 트랜잭션은 현자 k의 계좌에 얼마가 있는지 읽습니다. 그리고 20만원을 송금해서 100-20 = 80만원을 현재 계좌에 write합니다. 그리고 이때 두 번째 트랜잭션이 발생합니다. 그래서 현재 H계좌에 얼마가 있는지 확인하고 30만원을 입금한 후 230만원으로 write합니다. 그리고 첫 번째 트랜잭션에서 H 계좌를 읽어 230만원임을 확인한 후 20만원을 더해 총 250만원을 write한 후에 commit 하게 됩니다. 

  하지만 커핏만 이후에 트랜잭션 2번이 abort가 발생했다고 해봅시다.

출처: 쉬운코드

그러면 트랜잭션 2번을 rollback하게 됩니다. rollback은 트랜잭션의 atomicity 속성에 의해서 트랜잭션 이전 상태로 돌려놓는 것입니다. 트랜잭션 2번은 230만원으로 write했었기 때문에 이전상태인 200만원으로 다시 돌려놔야 합니다.

출처: 쉬운코드

여기서 주의할 점이 있습니다. 트랜잭션 1번은 트랜잭션 2번이 write한 230만원에 의존해서 230만원이라고 read한 후 20만원을 더해서 250만원으로 write하였습니다. 그럼 트랜잭션 2번이 rollback하면 이것에 의존하고 있던 트랜잭션 1은 어떻게 될까요?

출처: 쉬운코드

생각해 보면 트랜잭션 2를 read해서 write한 트랜잭션 1도 함께 rollback을 해주어야합니다. 하지만! 트랜잭션 1은 이미 250만원을 write한 후 commit을 했기 때문에 rollack이 불가능 합니다. 

트랜 잭션 1은 이미 commit된 상태이므로 durability 속성 때문에 rollback.할 수 없습니다. 

*durability 는 한번 커밋된 속성은 rollback 될 수 없다!

unrecoverable schedule

이처럼 schedule 내에서 commit된 트랜잭션이 rollback된 트랜잭션이 write 했었던 데이터를 read한 경우을 unrecoverable schedule이라고 합니다. 그래서 rollback을 해도 이전 상태로 회복 불가능할 수 있기때문에 이런 schedule은 DBMS에서 허용하면 안됩니다. 그러면 어떤 schedule이 recoverable 할까요?

recoverable schedule

회복 가능한 스케줄이 되려면 위 예시에서는 트랜잭션의 커핏 순서를 고려해보아야합니다. 트랜잭션 1의 read가 트랜잭션 2가 write한 230만원에 의존하고 있기 때문에 트랜잭션 2를 먼저 커밋하고 그 다음에 트랜잭션 1을 커밋하는 방법을 생각해 볼 수 있습니다.

출처: 쉬운코드

결국 여기서 핵심은 트랜잭션에 의존관계가 있는 경우, 여기서는 트랜잭션 1이 트랜잭션 2에 의존하고 있습니다. 그래서 이렇게 의존하고 있는 트랜잭션1은 트랜잭션이 2가 commit or rollback을 할 때까지 기다린 후에 operation을 진행합니다. 즉, 트랜잭션 1이 어떤 commit이나 rollback을 하기전까지는 commit하지 않습니다.

출처: 쉬운코드

따라서 이런 스케줄을 recoverable schedule이라고 합니다. 이런 회복 가능한 스케줄은 rollback을 할 때 이전 상태로 온전히 돌아갈 수 있기 때문에 DBMS는 이런 스케줄만 허용해야 합니다. 

cascading rollback

그렇게 하면 하나의 트랜잭션이 rollback을 하면 의존성이 있는 다른 트랜잭션도 같이 연쇄적으로 rollback을 합니다. 하지만 이 cascading rollback은 여러 트랜잭션의 rollback이 연쇄적으로 발생한다면 처리하는 비용이 많이 들게 됩니다. 이렇게 비용이 많이 발생하는 문제를 어떻게 해결할 수 있을까요?

데이터를 write한 트랜잭션이 commit/rollack 한 뒤에 데이터를 read하는 스케줄만 허용하자!

즉, 위 예시에서는 트랜잭션 1이 230만원으로 write한 후 commit이나 rollback을 하지 않을 상황에서 트랜잭션 2가 read한 것이기 때문에 추후 cascading rollback으로 인한 비용 문제가 발생 할 수 있습니다. 그래서 데이터를 write한 트랜잭션이 commit or rollback한 뒤에 또 다른 트랜잭션이 read하는 스케줄을 허용하자는 의미입니다!

출처: 쉬운코드

이런 방식으로 하면 만약 트랜잭션 1이 abort로 인해서 atomicity 속성에 따라 rollback을 해야하는 경우 트랜잭션 이전 상태로 돌아가기 때문에 아무 일도 없었던 여기서는 초기 상태로 돌아가게 됩니다. 그러면 트랜잭션 2만 rollback을 하게되는 셈입니다. 

출처: 쉬운코드

그러면 트랜잭션 2는 사라지게 되고 남아있는 트랜잭션 1이 read/write 한 후 커밋을 통해 트랜잭션을 종료하게 됩니다.

출처: 쉬운코드

cascade-less schedule

이렇게 스케줄 내에서 commit되지 않은 트랜잭션들이 write한 데이터를 다른 트랜잭션이 읽지 않는 것을 cascade-less 스케줄이라고 합니다. 그러면 이 스케줄은 아무런 문제가 없을까요? 새로운 예시를 통해 알아보겠습니다.

출처: 쉬운코드

먼저 직원이 1만원으로 write하였습니다. 그리고 직원 트랜잭션을 커밋하기 전에 사장님 트랜잭션이 2만원으로 write하고 커밋을 하였습니다. 그리고 직원 트랜잭션을 마무리 하려는데 abort가 발생해서 rollback을하여 다시 처음 가격이 3만원으로 돌아가게 되었습니다. 결국 사장님 트랜잭션이 사라지게 된 셈이죠!

출처: 쉬운코드

위 상황은 cascadeless schedule입니다. 왜냐하면 스케줄 내에서 어떤 트랜잭션도 commit되지 않은 트랜잭션들이 write한 데이터를 읽지 않았기 때문입니다. 여기서는 직원 트랜잭션이 사장 트랜잭션이(커밋되기전에) write한 데이터를 읽지 않았습니다. 그런데 트랜잭션 2 즉, 사장님의 트랜잭션의 결과가 사라지게 된 것이죠! 이를 해결하기 위해 좀 더 보강이 필요합니다.

Strict schedule

스케줄 내에서 어떤 트랜잭션도 commit되지 않은 트랜잭션들이 write한 데이터는 쓰지도/읽지도 않는 경우 입니다. 그래서 위 예시는 cascadeless schedule은 맞지만 strict schedule은 아닌것입니다. 이런 스케줄은 rollback을 할 때 recovery가 쉽습니다. 즉, 트랜잭션 이전 상태로 돌려놓기만 하면 됩니다.

출처: 쉬운코드

최종 정리

  • unrecoverable schedule: 회복 불가능 -> DBMS에서 허용 하지 않는다.
  • recoverable schedule은 허용한다. -> 트랜잭션이 의존성이 있는 경우 의존하고 있는 트랜잭션이 commit or rollback할 때 까지 commit하지 않는 것!
    • cascading schedule: 연쇄 operation -> 비용 많아 든다.
    • cascadeless schedule: 커밋이나 rollback하기 전 트랜잭션이 write한 데이터를 읽지 않는 것.
    • strict schedule: commit or rollback하기 전 트랜잭션이 write한 데이터를 쓰지도/읽지도 않는 것!

출처: 쉬운코드

그래서 이렇게 의존하고 있는 트랜잭션1은 트랜잭션이 2가 commit or rollback을 할 때까지 기다린 후에 operation을 진행 합니다. 즉, 트랜잭션 1이 어떤 commit이나 rollback을 하기전까지는 commit하지 않습니다. 이는 트랜잭션이 recoverability를 갖는다고 할 수 있습니다.

concurrency control provides serializability & recoverability.

728x90

'CS 지식 > 데이터베이스' 카테고리의 다른 글

DB - hashing  (0) 2023.12.15
트랜잭션 - concurrency control 기초(1)  (1) 2023.12.08
DB - transaction  (1) 2023.12.07