트랜잭션은 DBMS에서에서 데이터를 다루는 논리적인 작업의 단위
이다. 데이터베이스의 무결성을 유지하기 위해 원자성, 일관성, 고립성, 영구성
의 성질을 갖게 된다.
보통 단일 SQL 문을 사용하여 데이터를 다루게 되는데 여러 개의 SQL 문을 순차적으로 수행해서 다루기도 한다. 데이터베이스에서 트랜잭션을 정의하는 이유는 다음과 같다.
DBMS는 트랜잭션이 원자성, 일관성, 고립성, 지속성을 유지할 수 있도록 지원해준다.
회복관리자 프로그램 : 데이터베이스가 변경한 내용을 로그로 기록하고 있다가 트랜잭션에 문제가 생겼을 때 원래 상태로 되돌리는 것
데이터베이스는 공유를 목적으로 하기에 가능한 많은 트랜잭션을 동시에 수행시켜야 한다. 동시에 수행되는 트랜잭션은 다른 트랜잭션이 같은 데이터를 공유하고 있다는 사실을 모를 수 있기 때문에 일관성이 훼손될 수 있다. 트랜잭션이 동시에 수행될 때 일관성을 해치지 않도록 트랜잭션의 데이터 접근을 제어하는 DBMS의 기능을 동시성 제어 라고 한다.
만약 두개의 트랜잭션이 각각 읽기만 수행한다면 동시에 진행해도 아무 상관이 없게 된다. 그러나, 두 트랜잭션 모두 하나의 데이터를 쓰기를 수행한다면 갱신손실이 발생할 수 있다.
갱신손실은 데이터베이스에서 절대 발생하면 안되는 현상이다.
갱신손실 문제를 해결하기 위해선 상대방 트랜잭션이 데이터를 사용하는지 여부를 알 수 있는 규칙이 필요하다. 즉 자신이 데이터를 수정 중인 사실을 알려주면 되는데 이를 LOCK을 통해서 알려주게 된다.
LOCK은 트랜잭션이 데이터를 읽거나 수정할 때 데이터에 표시하는 잠금 장치다. 자신이 사용할 데이터를 락으로 잠그면 다른 트랜잭션은 잠금이 풀릴 때 까지 기다려야 한다. 락이 걸려있는 데이터를 사용하기 위해선 다른 트랜잭션들은 Wait 상태로 대기하게 되기 때문에 갱신을 순차적으로 진행하여 갱신손실 문제를 해결할 수 있게 된다.
Commit은 트랜잭션의 종료를 알리는 SQL이다. Commit이면 commit이지 왜 부분 완료인 Partially Commited가 있는것일까?
이는 트랜잭션이 데이터베이스에 어떻게 저장되는지 과정을 살펴보면 된다.
트랜잭션은 데이터베이스의 저장된 테이블을 읽어와 주기억장치 버퍼에 저장한다. 버퍼에 저장된 데이터를 수정한 후 최종적으로 데이터베이스에 다시 저장하는 과정을 거치게 된다.
송금 예시를 보자
1. A 계좌의 값을 하드디스크에서 주기억장치 버퍼로 가져온다.
2. B 계좌의 값을 하드디스크에서 주기억장치 버퍼로 가져온다.
3. A 계좌에서 10,000원을 인출한 값을 저장한다.
4. B 계좌에서 10,000원을 입금한 값을 저장한다.
5. A 계좌의 값을 데이터베이스에 기록한다.
6. B 계좌의 값을 데이터베이스에 기록한다.
트랜잭션으 사실적 종료는 데이터베이스에 기록한 6번이 된다. 그러나 DBMS는 1~4번까지 수행하고 사용자에게 완료사실을 알리고 5,6번은 DBMS가 책임지고 수행하게 된다.
DBMS가 동시에 많은 트랜잭션을 수행할 때, 각각의 트랜잭션이 하드디스크에 개별 접근하는 것을 피하고 DBMS가 일괄적으로 하드디스크에 접근하여 처리함으로써 사용자에게 빠른 응답성을 보장하기 위함
이다. 또한, 수정된 내용을 데이터베이스에 기록하는 5번 6번의 과정이 많은 시간을 소요하기 때문이다. 즉 다른 트랜잭션이 해당 테이블을 필요로 할 수 있기 때문에 트랜잭션은 임시 종료를 선언하고 DBMS가 이후 책임지고 데이터베이스에 기록하는 것이다.
References