1. Transaction
트랜잭션은 데이터베이스 뿐만 아니라 다른 분야에서도 사용되는 용어이다. 공통적인 의미는 해당 시스템에서의 상호작용의 단위라고 할 수 있다.
- 예를 들면, DBMS에서는 데이터베이스에 변경 사항을 반영하는 행위의 집합이라고 할 수 있을 것 같다. (집합의 원소 개수는 한 개일 수도 있고, 여러 개일 수도 있다.)
- 트랜잭션이라는 단위가 중요한 이유는 하나의 단위 안의 연산들은 기존의 결과에 대해 모두 적용되어야 하지 일부만 적용되서는 안 된다는 것이다. 다시 말해, 하나의 단위 안에 있는 연산들을 수행하던 도중 어떠한 원인이든지 간에 오류가 발생한다면 그 단위의 연산들의 결과는 어느 연산 하나라도 적용되면 안 된다. 만약 일부의 연산만 적용된다면, 기존의 데이터가 원치않는 데이터로 변질될 가능성이 있다는 것이고, 데이터의 일관성이 중요한 데이터베이스에서는 이러한 가능성이 데이터의 신뢰성을 깰 수 있다.
- 위에서 길게 서술했지만, 결국 데이터베이스에서는 데이터의 신뢰성을 위해
트랜잭션이 지녀야할 네 가지 속성(ACID)
이 있다.- Atomicity (원자성) : 각 트랜잭션은 시작부터 끝까지 결과를 보장해야 하며, 중도에 간섭이나 장애가 발생해서는 안 된다. 데이터베이스에 모두 반영되던가, 아니면 아무것도 반영되지 않아야 한다.
- Consistency (일관성) : 트랜잭션의 처리 결과가 항상 일관되어야 한다. (트랜잭션을 수행하는 도중에 데이터베이스가 변경되어도 트랜잭션의 수행 결과는 변경된 데이터베이스가 아닌 이전의 데이터베이스을 대상으로 수행된 것이다. 데이터베이스 변경에 관계없이 변경된 이후에도 일관된 수행 방식)
- Isolation (고립성) : 둘 이상의 트랜잭션이 동시에 수행되고 있을 떄, 어떤 트랜잭션도 다른 트랜잭션의 연산에 끼어들 수 없어야 한다.
- Durability (지속성, 내구성) : 하나의 트랜잭션이 성공적으로 수행되었을 경우에 그 결과는 영구적으로 반영되어야 한다. 손실이 일어나서는 안 된다.
- 위 속성들을 만족하여 트랜잭션이 수행됐다면, 그 트랜잭션은 오류없이 수행되어 commit되거나 도중에 오류가 발생하여 rollback되거나 둘 중 하나여야 한다.
2. 고립 수준 (Isolation Level)
고립 수준은 트랜잭션에서 일관성이 없는 데이터를 허용하도록 하는 수준을 의미한다.
일관성이 없는 데이터는 무조건 허용하지 않으면 되는 것 아닌가?
하는 의문이 들 수 있지만, 고립 수준을 조정하는 이유는 동시성과도 연관이 있기 떄문이다.
- 데이터의 무결성을 완벽하게 유지하지만, 트랜잭션의 고립 수준에 따라 동시성이 떨어질 수도 있고, 데이터의 무결성에 문제가 발생할 순 있지만, 동시성이 증가될 수도 있다.
(1) Read Uncommitted : SELECT 문을 수행하는 경우 해당 데이터에 Shared Lock이 걸리지 않는다.
- 사용자 x가 A라는 데이터를 B로 변경하고 커밋하지 않았지만, 사용자 y는 아직 커밋되지 않은 B라는 데이터를 읽을 수 있는 상황이 발생 (게다가, x가 데이터 A를 B로 변경한 트랜잭션을 Rollback할 경우, y는 잘못된 데이터를 읽은 상황이 된다. 이러한 y는 Dirty Read를 한 상황이며, Dirty Data를 갖고 있다고 말한다.)
- 동시성은 증가했지만, 데이터의 일관성을 지키지 못한 경우
- 나타날 수 있는 현상 : Dirty Read, Non-repeatable Read, Phantom Read
(2) Read Committed : SELECT 문이 수행되는 동안 해당 데이터에 Shared Lock이 걸린다. 해당 데이터에 대한 조작이 있었다면 Commit이 이루어져야 접근 가능하다.
- 사용자 x가 A라는 데이터를 B로 변경하고 커밋하지 않으면, 사용자 y는 해당 데이터에 접근할 수 없다.
- 나타날 수 있는 현상 : Non-repeatable Read, Phantom Read
(3) Repeatable Read : 하나의 트랜잭션이 끝나기 전까지 그 범위 안에서 조회한 데이터는 항상 동일함을 보장한다.
- 트랜잭션 1이 완료되기 전까지 SELECT 문에서 사용하는 모든 데이터에 Shared Lock이 걸린다. 때문에 트랜잭션 2에서는 트랜잭션 1에서 사용 중인 데이터에 삽입(Insert)은 가능하지만 수정(Update)은 불가능하다.
- 나타날 수 있는 현상 : Phantom Read
(4) Serializable : 하나의 트랜잭션이 Commit될 때까지 모든 데이터에 Shared Lock이 걸리고 해당 데이터에 대해 수정, 삽입 둘 다 불가능하다.
- 데이터의 무결성은 완벽히 유지하지만, 동시성이 전혀 없는 경우
- Repeatable Read와 비슷하지만, 다른 트랜잭션에서 데이터를 삽입하는 것도 불가능하다.
격리 수준에 따라 발생하는 현상 세 가지
(1) Dirty Read : 아직 Commit하지 않아 완료되지 않은 어떤 트랜잭션에 의한 변경 사항을 다른 트랜잭션에서 조회하는 경우
(2) Non-repeatable Read : 한 번 읽어들인 데이터가 다른 트랜잭션에서 데이터를 삭제함으로써 Unreachable(도달할 수 없는) 상태가 되는 경우
(3) Phantom Read : 하나의 트랜잭션에서 데이터를 조회하는 도중에 다른 트랜잭션에서 해당 데이터에 추가하면, 추가된 데이터까지 조회가 되는데, 이 때 데이터를 추가했던 트랜잭션을 Rollback하면, 데이터를 조회 중인 트랜잭션이 존재하지 않는 데이터를 읽어들이는 경우