거두절미하고 시작한다. 이번에 알아볼 내용은 제목과 같다.
트랜잭션이란, 데이터베이스의 상태를 변화시키는 작업의 단위이다.
다음과 같은 질의어를 통해 데이터베이스에 접근하는 모든 행위를 일컫는다.
단 주의할 것은, 하나의 트랜잭션이 하나의 질의를 의미하는 것은 아니라는 것이다. 여러개의 질의를 통해 데이터베이스 상태를 변화시키는 큰 단위의 작업을 하나의 트랜잭션으로 정의할 수도 있다.
트랜잭션은 다음과 같은 특성을 지닌다. 흔히 ACID 특성이라고 부른다.
한 트랜잭션 내의 모든 연산들이 완전히 수행되거나, 전혀 수행되지 않아야한다.
어떤 트랜잭션이 수행되기 전에 데이터베이스의 상태가 일관적이었다면, 트랜잭션이 수행된 이후에도 일관된 상태여야한다.
즉, 데이터베이스의 특정 제약조건이 트랜잭션 수행 전에 만족되고 있었고, 그 일관적인 상태를 유지중었다면 트랜잭션 수행 이후에도 특정 제약조건을 만족하는 데이터베이스여야 한다.
한 트랜잭션이 데이터를 갱신하는 동안, 이 트랜잭션이 완료되기 전까지는 다른 트랜잭션들이 갱신중인 데이터에 접근하지 못하도록 한다.
일단 한 트랜잭션이 완료되면 이 트랜잭션이 갱신한 것은 그 후에 시스템에 고장이 발생하더라도 손실되지 않는다.
사실 이러한 트랜잭션은 데이터베이스를 안전하게 잘 이용할 수 있도록 제시된 개념이다. 이러한 트랜잭션이 보장되기 전, lost update problem 이라는 문제점이 존재했다. 이는 두 개의 트랜잭션이 동시에 하나의 아이템을 변경했을 때 나타나는 문제인데, 트랜잭션이 지원되는 현대의 DBMS에서는 발생하지 않는다.
그런데, 트랜잭션을 지원함에도 발생하는 문제점들이 있다. 지금부터 그 문제점들에 대해 알아본다.
특정 트랜잭션에서 변경하고 커밋되지 않은 상태의 값을 다른 트랜잭션에서 읽어올 경우 생겨나는 문제점이다. 다음의 그림을 보자.
그림과 같이 특정 트랜잭션에서 값을 write했더라도, 커밋 이전에 rollback을 통해 값을 되돌릴 수 있다. 그런데, 다른 트랜잭션에서 rollback 이전의 값을 읽어오게 되면, 앞선 특정 트랜잭션이 끝난 뒤에는 읽어온 값이 사라지게 된다. 이것을 dirty read problem
이라고 부른다.
'다시 반복될 수 없는 읽기'. 감이 오지 않는가? 바로 그림을 보자.
위와 같은 트랜잭션이 실행되었다고 하자. 트랜잭션 2가 실행되고 있는 도중, 트랜잭션 1에 의해 특정 값이 변경되었다. 물론, 변경 된 이후에도 트랜잭션 2는 종료되지 않았다.
그 결과가 어떤가?
트랜잭션 2는 자신이 실행되는 동안 동일한 데이터에 대해 조회를 요청했지만, 그 결과는 서로 다르다. '다시 반복될 수 없는 읽기'를 수행한것이다.
이렇게 특정 트랙잭션이 하나의 값을 두번 읽었을 때, 그 값이 서로 다른 경우를 non-repeatable read
라고 부른다.
귀신이다 귀신!!!
농담이다. 아니, 진담이다. 이 문제점은 정말로 귀신을 보는 문제점이다. 그림을 보자.
트랜잭션 2가 2번째 select 쿼리를 수행했을 때 응답받은 2번 행은 이전의 select query 수행 결과에선 없었던 행이다. 귀신이다! 귀신!!!!
이렇게, 특정 트랜잭션에서 복수회 DB 조회를 시도했을 때, 그 쿼리의 수행결과가 달라져 잘못된 값이 들어오는 문제를 phantom read problem
이라 부른다.
non-repeatable read
와 똑같아 보일 수 있는데, non-repeateable
read는 단일한 값에 대해서, phantom read problem
은 다수 행의 조회 결과에 대해 나타날 수 있는 문제점이다.