동시성 제어
곤지암 스키장은 슬로프 정원제라고 동 시간대 입장 인원을 3,500명으로 제한한다.
이렇게 하게 되면 동 시간대 사람이 최대 3,500명만 입장하기 때문에 리프트를 타기 위한 줄이 짧아질 것이다.
만약 3,500명으로 제한하지 않고 사람이 몰리게 된다면 사고가 나거나 기다리는 시간이 엄청 길어질 것이다.
트랜잭션도 비슷하다.
한 개의 트랜잭션이 끝나고 다음 트랜잭션을 수행하면 데이터베이스 일관성이 아무 문제가 안 생긴다.
하지만 데이터베이스는 공유하여 사용하기 때문에 트랜잭션을 동시에 수행해야 하는데
다른 트랜잭션이 데이터를 공유하고 있다는 사실을 모르는 상황에선 일관성이 훼손될 수 있다.
트랜잭션이 동시에 수행될 때 일관성을 해치지 않도록 접근을 제어하는 DBMS의 기능을 동시성 제어라고 합니다.
Transaction Schedules
트랜잭션 스케쥴이란
데이터베이스의 일관적인 상태를 유지하기 위해 동시에 실행되는 트랜잭션들의 연산 순서를 정하는 것을 의미한다.
연산 순서에 따라 결과가 달라지기 때문에 병행 수행을 하기 위해서는 스케줄이 중요하다.
직렬 스케줄 (serial schedule)
인터리빙 방식을 이용하지 않고 각 트랜잭션 별로 연산들을 순차적으로 실행시키는 것.
모든 트랜잭션이 완료될 때까지 다른 트랜잭션의 방해를 받지 않고 독립적으로 수행된다.
인터리빙(Interleaving) : 트랜잭션을 연산 단위로 번갈아가며 수행하는 방식.
비직렬 스케줄 (nonserial schedule)
인터리빙 방식을 이용해서 트랜잭션을 병행해서 수행시키는 것이다.
비직렬 스케줄에 따라 여러 트랜잭션을 병행 수행하면 갱신손실, 모순성, 연쇄복귀 등 문제가 발생할 수 있다.
직렬 가능 스케줄 (serializable schedule)
직렬 스케줄에 따라 수행한 것과 같이 정확한 결과를 생성하는 비직렬 스케줄이다.
모든 트랜잭션을 순차적으로 인터리빙 없이 실행한 결과를 내는 비직렬 스케줄이다.
충동 직렬 가능 스케줄 (conflict serializable)
동일한 데이터에 대해 두 트랜잭션이 있다고 가정했을 때, 적어도 하나의 연산이 write인 경우 충돌이라 할 수 있다.
복구 가능한 스케줄(Recoverable Schedule)
스케줄은 serializable해야 하고, 복구 가능해야 한다.
만약 T2가 T1에 의해 변경된 데이터를 사용할 때, T1이 commit 되기 전에 T2는 commit 하면 안 된다.
그래야 T1이 중단될 때, T2도 중단될 수 있다.
캐스케이드 스케줄(Cascade Schedule)
T1이 실패하면 T2, T3 모두 롤백돼야 한다.
이러한 특징을 가진 스케줄인데 복구 가능하지 않은 스케줄을 만든다.
그래서 캐스케이드 스케줄은 다른 트랜잭션이 읽기 전에 commit해야 한다.
데이터베이스 락(Lock)
락(Lock)이란 DB는 여러 사용자들이 같은 데이터를 동시에 접근하는 상황에서, 데이터의 무결성과 일관성을 지키기 위해 락을 사용합니다.
ex) 티켓예약, 계좌이체, 수강신청
Lock의 종류
공유 락(Shared Lock)
데이터를 변경하지 않는 읽기 명령에 대해 주어지는 Lock으로 여러 사용자가 읽어도 데이터 일관성에는 아무 영향을 주지 않기 때문에, 공유락 끼리는 접근이 가능하다.
베타 락(Exclusive Lock)
데이터에 변경을 가하는 쓰기 명령들에 대해 주어지는 Lock으로 다른 세션이 해당 자원에 접근하는 것을 막습니다.
업데이트 락(Update Lock)
데이터를 수정하기 위해 베타 락을 걸기 전, 데드 락을 방지하기 위해 사용되는 Lock입니다.
Lock 사용 규칙
- 데이터에 락이 걸려있지 않으면 트랜잭션은 락을 걸 수 있다.
- 트랜잭션이 데이터를 읽기만 할 경우 공유락을 요청하고, 읽거나 쓰기를 할 경우 베타 락을 요청한다.
- 다른 트랜잭션이 데이터에 공유 락을 걸어두면, 공유 락의 요청은 허용하고 베타 락의 요청은 허용하지 않는다.
- 다른 트랜잭션이 데이터에 베타 락을 걸어두면, 공유 락과 베타 락의 요청 모두 허용하지 않는다.
- 트랜잭션이 락을 허용받지 못하면 대기 상태가 된다.
갱신손실 문제
갱신손실 문제는 두 개의 트랜잭션이 한 개의 데이터를 동시에 갱신할 때 발생한다.
락을 사용하면 갱신손실 문제를 해결할 수 있다.
확장 단계
트랜잭션이 시작될 때, 초기에 공유 락을 획득하고 다른 트랜잭션과 충돌을 최소화 한다.
공유 락을 가진 트랜잭션은 필요에 따라 베타 락으로 확장할 수 있다.
수축 단계
트랜잭션이 갱신 작업을 수행하기 위해 베타 락을 획득하고, 베타 락을 획득하면 공유 락을 해제한다.
이런 과정을 통해 갱신 작업을 빠르게 이루어질 수 있게 한다.
'CS > 데이터베이스' 카테고리의 다른 글
RDB - NoSQL 차이점 (1) | 2024.03.18 |
---|---|
트랜잭션 격리 수준 (0) | 2024.03.14 |
트랜잭션 (0) | 2024.03.13 |
ERD-정규화 (0) | 2024.03.11 |
Key (0) | 2024.03.10 |