동시성 제어
는 여러 유저가 동시에 여러 트랜잭션을 수행하는 환경에서 부정확한 결과를 야기할 수 있는 문제를 방지한다.
Serial schedule
: 하나에 한 트랜잭션을 수행할 수 있게 트랜잭션 순서를 정한다.Non-serial schedule
: 여러 트랜잭션을 동시에 수행한다.Serializable
: serial schedule을 하지만 non-serial schedule처럼 보이게 한다.Input
: 데이터베이스의 block을 읽어 메인 메모리 버퍼에 저장한다.
Output
: 메인 메모리 버퍼를 데이터베이스에 저장한다.
Read
: 메인 메모리 버퍼로부터 데이터베이스 block을 프로그램으로 가져온다.
Write
: 프로그램값을 메인 메모리 버퍼에 적는다.
어떤 트랜잭션이 업데이트한 것을 다른 트랜잭션이 덮어씀으로 인해 업데이트가 날라간다.
T1은 X에서 Y로 10만을 보내고 T2가 X에 5만을 더한다. T1, T2를 수행한 후 X는 초기값에서 5만이 빠진 25만이 되어야 한다.
T1 수행 중간에 T2가 X를 read함으로써 T1의 update를 덮어버린다.
완료되지 않은 트랜잭션 데이터를 읽는다.
T1은 M.Jung 계좌에 10만을 빼고 T2는 계좌들의 평균 금액을 select한다.
T1이 10만을 빼고 ROLLBACK을 하게 되는데 ROLLBACK 전에 T2가 수행되면서 M.Jung의 계좌에서 10만이 빠진 것을 반영한 평균 계좌 금액을 리턴하게된다.
한 트랜잭션이 같은 데이터를 여러 번 읽을 때 서로 다른 값을 읽는다.
T2가 같은 데이터를 두 번 접근하게 되는데 중간에 T1이 수행되면서 T2가 첫 번째 접근했을 때와 두 번째 접근했을 때의 값이 달라진다.
가상의 비행기 예약 시스템은 3가지 쿼리로 구성된다 하자.
(1) 빈 좌석 확인, (2) 판매 좌석++, (3) 예약 확정
만약 빈 자리가 1개일 경우에 2명이 동시에 예약 시스템 트랜잭션에 진입한다면, 1좌석에 2명이 배치될 수 있다.
Locking
은 트랜잭션의 동시성 제어에 주로 사용되는 방법이다.
트랜잭션이 데이터에 접근하면 unlock 전까지 해당 트랜잭션이 데이터 접근을 독점해 데이터 액세스에 대한 Mutual Exclusive를 보장한다.
각 트랜잭션이 데이터에 접근할 때마다 lock table에 lock 정보를 보관한다.
트랜잭션이 데이터에 접근해 점유를 끝내면 unlock을 하여 lock을 풀어준다.
X-lock
S-lock
lock request 단계, unlocking 단계로 구성된다.
lock contracting phase는 lock expanding phase 이후에 시작한다.
unlock이 되었을 때, lock contracting phase가 시작된다.
Lock expanding phase
: 트랜잭션이 lock 연산만 가능하고 unlock은 할 수 없다.
Lock contracting phase
: 트랜잭션이 unlock 연산만 가능하고 lock은 할 수 없다.
그림 9.12처럼 little by little로 unlock하거나 그림 9.13처럼 한 번에 전체를 unlock 할 수 있다.
lock point는 특정 트랜잭션에 필요한 모든 lock을 request한 시점이다.
2PL에서 발생할 수 있는 문제 중 하나이다. 2개 이상의 트랜잭션이 서로의 unlock을 하염없이 기다리게 돼 다음 작업을 진행하지 못 하는 상태를 말한다.
사전에 deadlock을 사전 방지하는 것을 마련하거나 process 우선순위와 같은 기준점을 적용해 victim을 선발함으로써 deadlock을 피할 수 있다.
만약 여러 튜플에 액세스하는 트랜잭션을 수행하는 경우, 수행시 튜플 하나하나에 lock과 unlock을 반복한다면 lock을 걸고 unlock을 수행하고 lock 테이블을 확인하는 시간이 길어질 것이다. 트랜잭션으로부터 DB전체의 lock인지 record 수준의 lock인지를 트랜잭션이 액세스할 튜플에 따라 구분할 필요가 있다.
하나의 트랜잭션에서 lock을 할 데이터 단위가 2개 이상인 경우를 multiple granularity라고 한다. 데이터베이스의 lock 단위는 database, relation, tuple 등이 있다.
5개의 튜플이 하나의 블록에 있고 T1은 t1, t4에 접근하고 T2는 t2에 액세스한다고 하자. 만약 lock 단위가 tuple인 경우, T1과 T2는 동시에 트랜잭션 작업을 할 수 있다. 하지만 T1의 lock 단위가 disk block(block)이 된다면, T1에서 작업을 수행할 때 X-lock을 걸었다고 했을 때 T2는 T1의 unlock을 기다려야 한다.