본문 바로가기
컴퓨터공학/데이터베이스

트랜잭션

by Daniel.kwak 2018. 10. 31.

목표

1.트랜잭션의 개요

2.트랜잭션의 특성(ACID)

2.동시성 제어

3.회복




트랜잭션 개요

항공기 예약, 은행, 신용카드 처리 등에서는 대규모 데이터베이스를 수백, 수천명 이상의 사용자들이 동시에 접근한다. 많은 사용자들이 동시에 서로 다른 부분 또는 동일한 부분을 접근하면서 데이터베이스를 사용하는 것이다. 동시성 제어란 동시에 수행되는 트랜잭션들이 데이터베이스에 미치는 영향은, 이들이 순차적으로 수행되었을때의 영향과 같도록 보장하는것을 말한다. 다수 사용자가 데이터베이스를 동시에 접근해서 사용하더라도 데이터베이스의 일관성을 유지하는 것이다. 

회복이란 데이터베이스를 갱신하는 도중에, 시스템이 고장나도 데이터베이스의 일관성을 유지하는것을 말한다. 


데이터베이스 시스템에서 볼 수 있는 몇 가지 트랜잭션의 예를 보자.

1.전체 사원의 급여를 6%씩 인상한다고 해보자. 질의는 

UPDATE EMPLOYEE SET SALARY = SALARY * 1.06; 이다. 

이때 500명 전원의 급여가 수정되거나, 한 명의 급여도 갱신되지 않도록 DBMS가 보장해야 한다. 

만약 320번째 사원까지 급여가 업데이트 됐는데, 시스템이 다운되어버리면 DBMS는 어떻게 대응해야 하는가? ->로그를 유지하여 어디까지 업데이트 됐는지 알아야 한다.


2.사용자1이 자신의 계좌에서 만원을 인출하여 사용자2에게 만원을 송금하는 경우를 생각해보자. 두 개의 SQL질의가 동시에 실행되거나, 실행되지 않아야 한다. 

기본적으로 각각의 SQL문이 하나의 트랜잭션으로 취급되지만, 두 개 이상의 SQL문들을 하나의 트랜잭션으로 취급하려면, 사용자가 이를 명시해야 한다.





트랜잭션의 특성

1.원자성(Atomicity)

-한 트랜잭션 내의 모든 연산들이 완전히 수행되거나, 전혀 수행되지 않음(all or nothing)을 의미한다.

-DBMS의 회복모듈은 시스템이 다운되는 경우에, 부분적으로 데이터베이스를 갱신한 트랜잭션의 영향을 취소함으로써, 원자성을 보장한다.


2.일관성(Consistency)

-어떤 트랜잭션이 수행되지 전에 데이터베이스가 일관된 상태를 가졌다면, 트랜잭션이 수행된 후에 데이터베이스는 또 다른 일관된 상태를 가진다.

-트랜잭션이 수행되는 도중에는 일시적으로 일관된 상태가 아닐 수 있다.


3.고립성(Isolation)

-한 트랜잭션이 데이터를 갱신하는 동안 이 트랜잭션이 완료되기 전에는 갱신 중인 데이터를 다른 트랜잭션들이 접근하지 못하도록 해야 함.

-다수의 트랜잭션들이 동시에 수행되더라도, 그 결과는 어떤 순서에 따라 트랜잭션들을 차례로 수행한 결과와 같아야 한다.

-DBMS의 동시성 제어 모듈이 트랜잭션의 고립성을 보장함.

-응용 수준에 따라서 다양한 고립수준을 제공한다.


4.지속성(Durability)

-일단 하나의 트랜잭션이 완료되면, 이 트랜잭션이 갱신한 것은 그 후에 시스템이 고장이 발생하더라도 손실되지 않는다. 

-완료된 트랜잭션의 효과는 시스템이 고장난 경우에도 데이터베이스에 반영된다. ->DBMS의 회복모듈이 지속성을 보장



트랜잭션의 완료(commit)

트랜잭션에서 변경하려는 내용이 데이터베이스에 완전하게 반영됨. SQL 구문상으로 COMMIT WORK.


트랜잭션의 철회(abort)

트랜잭션에서 변경하려는 내용이 데이터베이스에 일부만 반영된 경우에, 원자성을 보장하기 위해서 트랜잭션이 갱신한 사항을 트랜잭션이 수행되기 전으로 되돌림

SQL 구문상으로 ROLLBACK WORK이다.





트랜잭션이 성공하지 못하는 원인은 다양하다. 시스템이나 사이트 고장, 트랜잭션 고장, 매체 고장, 통신 고장, 부주의 등등...




동시성 제어

대부분의 DBMS는 다수 사용자 용이다. 여러 사용자들이 동시에 동일한 테이블을 접근하기도 하는데, 동시성 제어 기법은 여러 사용자들이 다수의 트랜잭션들을 동시에 수행하는 환경에서 부정확한 결과를 생성할 수 있는, 트랜잭션들 간의 간섭이 생기지 않도록 한다. 




용어들을 짚고 넘어가자.

직렬 스케쥴(serial schedule) : 여러 트랜잭션들의 집합을 한 번에 한 트랜잭션씩 차례대로 수행한다.

비직렬 스케쥴(non-serial schedule) : 여러 트랜잭션들을 동시에 수행한다.

직렬가능(serializable) : 비직렬 스케쥴의 결과가 어떤 직렬 스케쥴의 수행 결과와 동등함.


만약 동시성 제어를 하지 않고 다수의 트랜잭션을 동시에 수행한다면 어떤 문제가 발생할까?

1.갱신손실(lost update): 수행중인 트랜잭션이 갱ㅇ신한 내용을 다른 트랜잭션이 덮어씀으로써 갱신이 무효가 되는것.


2.오손 데이터 읽기(dirty read) : 완료되지 않은 트랜잭션이 갱신한 데이터를 읽는것.


3.반복할 수 없는 읽기(unrepeatable read) : 한 트랜잭션이 동일한 데이터를 두 번 읽을 때 서로 다른 값이 읽히는 것.




로킹
데이터 항목을 로킹하는 개념은 동시에 수행되는 트랜잭션들의 동시성을 제어하기 위해 가장 널리 사용된다. 
락(lock)은 데이터베이스 내의 각 데이터 망혹과 연관된 하나의 변수이며, 각 트랜잭션이 데이터 항목에 접근할 때마다 요청한 락에 관한 정보틑 락 테이블에 유지된다.
트랜잭션에서 갱신을 목적으로 데이터에 접근할 때는 독점락(X-Lock,eXclusive lock)을 요청하고, 읽을 목적으로 데이터에 접근할 때는 공유락(s-lock, Shared-lock)을 요청함.
트랜잭션이 데이터 항목에 대한 접근을 끝내면 락을 해제한다.(unlock)
2단계 락 프로토콜이란 락을 요청하는 것과 락을 해제하는 것이 2단계로 이루어진다. 락 확장단계가 지나면 수축단계로 들어간다. 일단 락이 한개라도 해제되면 수축단계로 들어간다.


락 확장단계(1단계) : 트랜잭션이 데이터 항목에 대해 새로운 락을 요청할 수 있지만 보유하던 락을 하나라도 해제할 수는 없다.
락 수축단계(2단계) : 락 수축단계에서는 보유하고 있던 락을 해제할 수 있지만 새로운 락을 요청할 수 없다. 이 단계에서 락을 조금씩 해제할 수도 있고 한꺼번에 모든 락을 해제할 수도 있다. 
락 포인트 : 한 트랜잭션에 필요한 모든 락을 걸어놓은 시점

상황에 따라서 데드락이 발생할 수도 있다.




회복

어떤 트랜잭션을 수행하는 도충에 시스템이 다운되면, 그 트랜잭션의 수행 효과가 디스크의 데이터베이스에 일부 반영될 수도 있다. 또한 트랜잭션이 완료된 직후에 시스템이 다운됨다면 트랜잭션의 모든 갱신 효과가 주기억장치에서 디스크로 기록되지 않을 수도 있다.  

이러한 고장이 발생하기 전에 트랜잭션이 완료 명령을 수행했다면 회복 모듈은 이 트랜잭션의 갱신 사항을 재수행(REDO) 하여 트랜잭션 갱신이 지속성을 갖게 한다.

또는 트랜잭션이 완료 명령을 수행하지 못했다면 원자성을 보장하기 위해 이 트랜잭션이 데이터베이스에 반영했을 가능성이 있는 갱신을 취소(UNDO) 해야 한다. 


로그를 사용한 즉시 갱신

트랜잭션의 원자성과 지속성을 보장하기 위해 DBMS는 로그라고 부르는 특별한 파일을 유지한다. 데이터베이스의 항목에 영향을 미치는 모든 트랜잭션의 연산들에 대해서 로그 레코드를 기록한다.  각 로그 레코드는 로그 순서 번호(LSN)로 식별된다. 즉시 갱신에서는 트랜잭션이 데이터베이스를 갱신한 사항이 주기억장치의 버퍼에 유지되다가, 트랜잭션이 완료되기 전이라도 디스크의 데이터베이스에 기록될 수 있다. (완료 뿐 하니라 철회된 트랜잭션도 반영될 수 있음)




각 로그 레코드가 어떤 트랜잭션에 속한 것인가를 식별하기 위해 각 로그 레코드마다 트랜잭션 ID를 포함시킨다. 예시를 보자.




트랜잭션의 완료점(Commit Point)

한 트랜잭션의 데이터베이스 갱신 연산이 모두 끝나고 갱신 사항이 로그에 기록되었을 때 이다. DBMS의 회복모듈은 로그를 검사하여 [Trans-ID , start] 부터 [Trans-ID , commit] 로그 레코드가 모두 존재하는 트랜잭션들은 재수행 한다. start는 있지만 commit은 없는 경우 트랜잭션들은 취소한다. 


로그 먼저 쓰기(WAL:Write Ahead Logging)

만일, 데이터베이스 버퍼가 로그 버퍼보다 디스크에 먼저 기록될 경우, 로그 버퍼가 기록되지 전에 시스템이 다운되면 주기억 장치는 휘발성이므로 데이터베이스와 로그 버퍼의 내용은 전혀 남아 있지 않는다. 따라서 데이터베이스 버퍼보다 로그 버퍼를 먼저 디스크에 기록해야 한다.


체크포인트

시스템이 다운된 시점으로부터 오래전에 완료된 트랜잭션들은 이미 디스크에 반영되었을 가능성이 높다. DBMS가 로그를 사용해도 어떤 트랜잭션의 갱신사항이 주기억장치 버퍼로부터 디스크에 기록되었는가를 구분할 수 없기 때문에, 회복시 재수행할 트랜잭션의 수를 줄이기 위해, 주기적으로 체크포인트를 수행한다. 

체크포인트 시점에는 주기억장치의 버퍼가 디스크에 강제 기록되므로 체크포인트를 수행하면 디스크 상에서 로그와 데이터베이스의 내용이 일치하게 된다.

체크포인트 역시 로그 레코드에 기록된다. 


따라서 체크포인트를 할 때 수행되는 작업은 다음과 같다.

1.주기억 장치의 로그 버퍼를 디스크에 강제로 출력한다.

2.주기억장치의 데이터베이스 버퍼를 디스크에 강제로 출력한다. 

체크포인트를 했을때와 하지 않았을때의 예시를 보자. 




'컴퓨터공학 > 데이터베이스' 카테고리의 다른 글

뷰(VIEW)  (0) 2018.10.31
데이터베이스 정규화  (0) 2018.10.30
데이터베이스의 인덱스  (0) 2018.10.28
SQL  (0) 2018.10.28
관계 데이터 모델과 제약조건  (0) 2018.10.27
데이터베이스 시스템 개요  (0) 2018.10.27