쉬운 코드 채널의 Youtube 영상을 보고 정리한 내용입니다.
(2부) concurrency control 기초 : recoverability. 트랜잭션들이 동시에 실행될 때 rollback이 발생하면 어떤 일이 벌어질까요?
Unrecoverable Schedule
회복 불가능한 형태의 schedule로, DBMS는 이런 schedule을 허용하지 않는다.
여러 트랜잭션으로 이루어진 schedule에 대해 특정 트랜잭션을 롤백할 때, 다른 트랜잭션은 롤백할 수 없는 경우를 말한다.
예를 들어
k가 h에게 20만원 이체 할 때, h도 자기 계좌에 30만원을 입금하려고 할 때 아래와 같은 순서로 트랜잭션이 수행된다고 하자.
(1) T1. k의 계좌 잔액을 읽는 작업 (k_balance -> 100만원)
(2) T1. k의 계좌에서 20만원을 빼는 작업 (k_balance=80만원)
(3) T2. h의 계좌 잔액을 읽는 작업 (h_balance -> 200만원)
(4) T2. h의 계좌에 30만원을 더하는 작업 (h_balance=230만원)
(5) T1. h의 계좌 잔액을 읽는 작업 (h_balance -> 230만원)
(6) T1. h의 계좌에 20만원을 더하는 작업 (h_balance=250만원)
(7) T1. commit
위 작업이 모두 순서대로 수행된 뒤 문제가 생겨 T2를 rollback하게 되었다면?
T1은 이미 commit된 상태이므로 rollback을 할 수 없다.
그렇게 되면 T1은 유효하지 않은 데이터를 읽어서 작업을 한 셈이 된다. (4) - (5) - (6)
이렇게 schedule 내에서 commit된 transaction이,
rollback된 transaction이 write 했던 데이터를 읽은 경우 rollback을 해도 이전 상태로 회복 불가능하다.
Recoverable Schedule
그렇다면 어떤 schedule이 Recoverable 한가? commit의 순서가 중요하다.
의존하고 있는 트랜잭션이 커밋된다면, 함께 커밋해준다.
➡️ 위 예시에 따르면 T1은 T2가 커밋될 때 함께 커밋한다.
의존하고 있는 트랜잭션이 롤백을 해야 하는 상황이 오면, 먼저 커밋하지 않고 기다렸다가 롤백 시 함께 롤백한다. (abort)
➡️ 위 예시에 따르면 T1은 T2를 롤백할 때 함께 롤백한다.
이처럼, 그 어떤 트랜잭션도 자신이 읽은 데이터를 write한 트랜잭션이 먼저 commit/rollback 전까지는 commit하지 않는 경우를 말한다.
DBMS는 이러한 schedule만을 허용한다.
Cascadeless Schedule
schedule 내에서 어떤 트랜잭션도, 커밋되지 않은 트랜잭션들이 write한 데이터를 읽지 않는 schedule을 말한다.
다른 말로 Avoding Casacading Rollback이라고도 부른다.
Recoverable Schedule의 경우, 롤백을 할 때 의존성이 있는 다른 트랜잭션도 연쇄적으로 롤백된다.
➡️ 이러한 동작을 Cascading Rollback 이라 하는데, 처리하는 비용이 많이 든다.
그렇다면 애초에 'Cascading Rollback을 할 필요가 없는 Schedule' = Cascadeless한 Schedule만 허용하면 비용 문제가 해결된다.
Cascading Rollback을 할 필요가 없으려면?
데이터를 write한 트랜잭션이 커밋/롤백한 뒤에 데이터를 읽으면 된다. 이를 Cascadeless Schedule이라고 한다.
Unrecoverable schedule의 예시를 아래와 같이 Recoverable, Cascadeless하게 변경할 수 있다.
(1) T1. k의 계좌 잔액을 읽는 작업 (k_balance -> 100만원)
(2) T1. k의 계좌에서 20만원을 빼는 작업 (k_balance=80만원)
(3) T2. h의 계좌 잔액을 읽는 작업 (h_balance -> 200만원)
(4) T2. h의 계좌에 30만원을 더하는 작업 (h_balance=230만원)
(5) T2. commit
➡️ T1은 T2가 commit된 후에야 데이터를 읽고 작업을 한다. T2에 의존하는 작업은 아무것도 없다.
(6) T1. h의 계좌 잔액을 읽는 작업 (h_balance -> 230만원)
(7) T1. h의 계좌에 20만원을 더하는 작업 (h_balance=250만원)
(8) T1. commit
만약 (5)에서 T2를 rollback한다면, 남은 T1의 작업은 마치 T2가 원래 없었던 것처럼, 아래와 같이 진행된다.
(6) T1. h의 계좌 잔액을 읽는 작업 (h_balance -> 200만원)
(7) T1. h의 계좌에 20만원을 더하는 작업 (h_balance=220만원)
(8) T1. commit
Strict Schedule
Cascadeless Schedule에서 서로 다른 두 트랜잭션이 같은 데이터에 대해 write 작업을 할 때, 롤백을 하면 무조건 두 트랜잭션을 모두 롤백해야 한다.
(1) T1. 피자 가격을 1만원으로 변경한다.
(2) T2. 피자 가격을 2만원으로 변경한다.
(3) T2. commit
(4) T1. abort
➡️ 두 트랜잭션 중 커밋한 트랜잭션 T2의 피자 가격은 반영하고 싶어도, 결과가 함께 사라진다.
이런 현상을 방지하기 위해서, Strict Schedule은
schedule 내에서 어떤 트랜잭션도, 커밋되지 않은 트랜잭션들이 write한 데이터를 쓰지도 읽지도 않는 schedule을 말한다.
아래와 같이 실행될 것이다.
(1) T1. 피자 가격을 1만원으로 변경한다.
(2) T1. commit / abort
(3) T2. 피자 가격을 2만원으로 변경한다.
(4) T2. commit
이 schedule은 롤백할 때 recovery가 쉽다는 특징이 있다.
정리
Unrecoverable Schedule | 롤백 시 회복이 불가해 DBMS에서 허용하지 않음 | ||
Recoverable Schedule | 롤백 시 회복이 가능함 | ||
Casacdeless Schedule | Cascading rollback이 발생하지 않음 | ||
Strict Schedule | Casacdeless Schedule 중에서도 더 엄격함. 커밋되지 않은 트랜잭션들이 쓴 데이터를 쓰지도 읽지도 않는다. |
어떤 Schedule이 Recoverable하다는 것은?
- 해당 schedule의 어떤 트랜잭션도, 자신이 읽은 데이터를 쓴 트랜잭션이 commit/rollback 되기 전까지는 commit되지 않는 것.
이것과 Concurrency Control(동시성 제어)은 무슨 관련이 있나?
- 동시성 제어는 serializability와 recoverability를 제공한다.
복구가 쉬운 Strict Schedule이 단점은 무엇이 있을까?
- 동시적인 접근이 많이 일어날 때, 비동기적 처리가 어려워서 성능이 저하되지 않을까? (같은 데이터에 대해서 커밋될 때까지 기다려야함) -> 일단 내 뇌피셜.. 더 공부해보자.
'공부 > Database' 카테고리의 다른 글
Lock을 활용한 Concurrency Control 기법 (1) | 2023.10.10 |
---|---|
Transaction 격리가 되지 않을 때 발생할 수 있는 현상들 (0) | 2023.10.03 |
동시성 제어(Concurrency Control) 기초 (1) Schedule과 Serializability (0) | 2023.09.18 |
[Real MySQL 8.0] 05. 트랜잭션과 잠금 (2) MySQL의 격리 수준 (0) | 2023.09.13 |
[Real MySQL 8.0] 05. 트랜잭션과 잠금 (1) 트랜잭션, MySQL의 잠금 (0) | 2023.09.12 |