DB 관리시스템 혹은 이와 유사한 시스템에서 상호작용, 처리 등을 하기 위한 최소 단위이다.
트랜잭션은 단순히 업무처리의 단위가 아닌, 전체 시스템의 작동방식 및 업무효율을 결정하는 매우 중요한 항목이다.
이러한 트랜잭션이 요구하는 조건은 아래와 같다.
트랜잭션은 ACID라 불리는 4가지 원리를 기반으로 동작한다.
Atomic, 원자성
트랜잭션은 더이상 쪼갤 수 없는 최소한의 처리(작업) 단위이다. 성공 시 commit, 실패 시 roll back하며 부분 성공의 개념은 존재할 수 없다.
Consistency, 일관성
트랜잭션 도중 혹은 이후에 일관된 상태의 DB가 유지되어야 하며, 이러한 상태가 사용자에게 보여져야 한다.
→ 무결성, 결함이 있는 곳이 없어야 한다
Isolatio, 격리성
트랜잭션은 서로 간섭할 수 없다. 다만 동시 수정 작업을 진행할 경우 "직렬화"하여 처리하는데, 각 작업을 순차적으로 진행해야 한다.
※ 이러한 순차적인 수정 작업은 일관성에 의해, 모든 작업이 DB에 반영되어야 한다.
Durability, 영속성
시스템 오류 발생 시에도 트랜잭션에 의한 수정 내용은 유효하다. 단 필요시 로그를 이용하여 이전 상태로 복구하여야 한다.
트랜잭션은 기본적으로 서로 간섭할 수 없고, 수정 도중에 다른 트랜잭션이 중복 수정을 할 수 없다.
그러나 실무에서는 시스템 환경 및 성능 이슈를 고려해야 하므로, 트랜잭션 격리수준을 표준화하여(ANSI) 관리한다. 즉 이상적인 격리수준은 실제 실무에서는 실현이 쉽지 않아, 보통은 완화된 기준으로 트랜잭션을 관리하는 곳이 많다.
Read Uncommitted
Commit을 하지 않은 읽기.
트랜잭션에서 처리 중인, 아직 Commit 되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용한다.
Read Comitted
Commit한 읽기.
트랜잭션에서 Commit이 확정된 데이터만 다른 트랜잭션이 읽는 것을 허용한다.
Repeatable Read
트랜잭션 내 쿼리를 두 번 이상 실행할 경우, 첫번째 쿼리의 레코드가 사라지거나 데이터가 변화하는 것을 방지한다.
Serialzable
트랜잭션 내 쿼리를 두 번 이상 실행할 경우, 첫번째 쿼리에 있던 레코드가 사라지거나 바뀌거나 생성되지 않는다.
이때 가장 이상적인 격리 수준은 Serialzable 이지만, DBMS를 운영하는데 동시성이 크게 하락하고 성능 이슈가 발생한다.
→ 실제 실무에서는 Serialzable보다 낮은 수준으로 관리한다.
Serialzable에서 완화된 트랜잭션 격리수준에 따라 다양한 이슈사항이 발생할 수 있다.
Dirty Read
Dirty 읽기, 트랜잭션이 commit을 하기 전에 다른 트랜잭션에서 데이터를 읽을 수 있다.
이때 변경후 commit되지 않은 값을 읽었을 시, 변경 트랜잭션이 해당 트랜잭션 혹은 쿼리를 roll back한다.
roll back할 경우 그 값을 읽는 트랜잭션은 비일관 상태에 놓이게 된다(모든 사용자에게 일관된 상태의 DB가 아님).
Non-Repeatable Read
애매한 읽기, 트랜잭션이 읽는 데이터를 다시 읽을 때 2회 읽은 이후의 결과가 1회 결과와 다른 현상이다.
한 트랜잭션 내 쿼리 수행 도중, 다른 트랜잭션이 값을 수정 및 삭제하여 쿼리 결과가 다르게 보이는 현상이다.
→ 계좌 인출 시 금액 부족 현상 등이 발생하는 경우
Phantom Read
유령 읽기, 특정 트랜잭션을 읽을때 선택할 수 없는 데이터가 나타나는 현상이다.
한 트랜잭션에서 쿼리를 두 번 수행했는데, 첫번째 쿼리에 없던 유령 레코드가 두번째 쿼리에 나타난다.
각 격리수준에 따라 발생할 수 있는 이슈사항은 다음과 같다.
패스트캠퍼스 - 데이테베이스와 SQLD