이전 글에서 이어집니다.
이번 글에서는 recoverable schedule, cascadeless schedule, strict schedule에 대해 살펴보겠습니다.
K가 H에게 20만원을 입금할 때, H도 본인 계좌에 30만원을 입금한다면
회복 불가능한 스케줄은 다음과 같은 상황에서 발생합니다:
이렇게 되면 T1이 이미 T2가 수정한 데이터를 읽고 사용한 상태에서, T2의 변경이 롤백되어 데이터의 일관성과 무결성이 깨지는 문제가 발생합니다. 이런 경우에는 unrecoverable schedule (회복 불가능한 스케줄)이라고 합니다.
DBMS는 이러한 스케줄이 발생하지 않도록 제어해야 합니다.
recoverable schedule(회복 가능한 스케줄)을 구성하기 위해서는 트랜잭션 간의 의존성을 고려해야 합니다. 예를 들어, 한 트랜잭션이 다른 트랜잭션이 변경한 데이터를 읽을 경우, 의존성이 형성됩니다. 이때 중요한 원칙은 "의존성을 가진 트랜잭션은 의존하는 트랜잭션이 종료될 때까지 commit을 하면 안된다"는 것입니다.
실제로는 다음과 같은 상황을 고려해야 합니다. 먼저, 트랜잭션 T1이 T2보다 먼저 시작되고, T2가 T1이 commit되기 전에 시작됩니다. T2가 수정한 데이터를 T1이 읽은 후 T1이 commit됩니다. 이후 T2가 롤백되는 상황이 발생한다면, T1은 이미 commit된 상태이므로 롤백할 수 없습니다. 이로 인해 데이터의 불일치가 발생하게 됩니다.
recoverable schedule을 구성하기 위해서는 의존성이 있는 트랜잭션이 commit되기 전까지는 의존하는 데이터를 변경한 트랜잭션이 commit되면 안됩니다. 이렇게 함으로써 롤백이 필요한 경우에도 데이터의 일관성과 무결성을 유지할 수 있습니다.
recoverable schedule은 데이터베이스 트랜잭션의 안전한 수행을 보장하는 핵심 개념 중 하나입니다.
rollback을 할 때 이전 상태로 온전히 돌아갈 수 있기 때문에 DBMS는 이런 schedule만 허용해야 합니다.
Cascading rollback은 하나의 트랜잭션이 롤백되면 의존하는 다른 트랜잭션들도 연쇄적으로 롤백되어야 함을 의미합니다.
이는 하나의 롤백이 여러 트랜잭션에 영향을 미칠 수 있기 때문에 처리 비용이 상당히 높아질 수 있습니다. 여러 트랜잭션의 롤백이 연쇄적으로 발생하면 전체 시스템의 안정성과 성능에 부정적인 영향을 미칠 수 있습니다.
Cascadeless schedule은 cascading rollback을 방지하기 위한 개념입니다. 이 개념은 데이터를 write한 트랜잭션이 commit 또는 rollback 한 후에 해당 데이터를 읽는 트랜잭션들만을 허용하도록 설계하는 것을 의미합니다.
즉, 스케줄 내에서 어떤 트랜잭션도 커밋되지 않은 트랜잭션이 write한 데이터를 읽지 않는 경우에만 cascadeless schedule이 성립합니다. 이렇게 함으로써 cascading rollback의 발생을 예방하고 전체 시스템의 안정성과 성능을 향상시킬 수 있습니다.
H 사장님이 3만원이던 피자를 2만원으로 낮추려는데 K 직원도 동일한 피자의 가격을 실수로 1만원으로 낮추려고 할 때 이런 schedule도 생길 수 있습니다.
T1에서 피자 가격을 1만원으로 변경하는 write 작업이 실행된 후, 커밋 전에 T2가 실행되어 피자 가격을 2만원으로 변경하는 write 작업이 실행된 후 커밋이 되었습니다.
그러나 T1 트랜잭션이 롤백됬을 경우, 피자 가격은 3만원이 됩니다.
이로 인해 T2에 결과가 사라지게 되었습니다.
해당 트랜잭션들은 cascadeless schedule 성립하는 상황임에도 불구하고 T2가 커밋이 됬음에도 결과가 사라지는 현상이 발생하였습니다.
이러한 문제를 해결하기 위해서는 기존의 cascadeless schedule 개념에 조금 더 보강이 필요합니다.
Strict schedule은 cascadeless schedule 개념을 보강한 것으로, 데이터를 write한 트랜잭션이 commit 또는 rollback 한 후에 해당 데이터를 읽는 트랜잭션들뿐만 아니라 해당 데이터를 쓰는 트랜잭션들만을 허용합니다.
Strict schedule은 롤백 시에도 복구가 용이하며, 트랜잭션 간의 의존성을 더욱 명확하게 관리할 수 있습니다.
데이터를 write한 트랜잭션이 commit 또는 rollback 한 후에 해당 데이터를 읽는 트랜잭션들만을 허용하는 것 뿐만 아니라 해당 데이터를 쓰는 트랜잭션들만을 허용해야 합니다.
앞선 예제는 cascadeless schedule은 맞지만 strict schedule은 아닙니다.
앞선 예제가 strict schedule이 되려면,
T1에서 피자 가격을 1만원으로 변경하는 write 작업이 실행되고 커밋 된 이후에 T2가 실행되어야 합니다.
이렇게 함으로써 데이터 변경 작업의 결과가 영구적으로 적용된 후에 해당 데이터를 사용하는 작업이 실행되도록 보장할 수 있습니다.