1. 트랜잭션
DB의 상태를 변환하는 하나의 논리적 기능을 수행하기 위한 작업 단위, 또는 한 번에 모두 수행되어야 할 일련의 연산. Commit 되거나 Rollback 됨
2. 트랜잭션의 성질 (ACID)
(1) Atomicity (원자성)
- 트랜잭션의 연산은 DB에 모두 반영되든, 전부 반영되지 않아야 한다.
- 트랜잭션 내 모든 명령은 반드시 완벽히 수행돼야 하고, 어느 하나라도 오류가 발생하면 트랜잭션 전부가 취소돼야 한다.
(2) Consistency (일관성)
- 데이터는 미리 정의된 규칙에서만 수정되어야 한다.
- DB의 모든 데이터는 여러 조건과 규칙에 따라서만 유효함을 가져야 한다.
- 트랜잭션이 실행을 성공적으로 완료하면 일관성 있는 DB 상태로 변환한다.
- 시스템이 가지고 있는 고정 요소의 상태는 트랜잭션 전후가 같아야 한다.
(3) Isolation (고립성)
- 둘 이상의 트랜잭션이 동시에 병행 실행되는 경우, 어느 한 트랜잭션 실행 중 다른 트랜잭션의 연산이 끼어들어서는 안 된다.
- 수행 중인 트랜잭션의 결과는 수행이 완료되기 전까지 다른 트랜잭션에서 참조할 수 없다.
(3 - 1) 트랜잭션의 격리 수준
복수의 트랜잭션이 동시에 처리될 때, 트랜잭션이 변경하거나 조회하고 있는 데이터에 대한 다른 트랜잭션의 조회를 얼마나 허용할지 결정해야 한다. 이를 얼마나 허용할 것인지가 아래의 네 수준으로 나뉘는데, 아래로 갈수록 격리성은 낮아지면서 동시성이 강해진다.
- SERIALIZABLE
- 트랜잭션을 순차적으로 진행한다.
- 여러 트랜잭션이 동시에 같은 행에 접근할 수 없다. (
SELECT
도 포함)
- 한 트랜잭션이 어떤 행에 접근하고 있다면, 그 행에 대해서 다른 트랜잭션은 대기한다.
- 교착 상태가 일어날 확률이 높고 성능이 떨어진다.
- REPEATABLE_READ
- 한 트랜잭션이 수정 중인 행을 다른 트랜잭션이 수정할 수 없게 한다.
- 단 새로운 행을 추가하는 것을 막지는 않는다.
- READ_COMMITTED
- 가장 많이 사용되는 격리 수준.
- 한 트랜잭션이 커밋하지 않은 정보는 읽을 수 없고, 커밋이 완료된 데이터에 대해서만 조회를 허용한다.
- 변경되었더라도 커밋되지 않았다면, 다른 트랜잭션에서는 해당 데이터가 커밋되기 전의 데이터를 읽는다.
- 어떤 트랜잭션이 접근한 행을 다른 트랜잭션이 수정할 수도 있다.
- READ_UNCOMMITTED
- 트랜잭션이 커밋하지 않은 정보도 읽을 수 있다.
- 가장 빠르다.
- 데이터 무결성을 위해서는 사용하지 않는 것이 좋지만, 거대한 양의 데이터를 어림잡아 집계하는 데에는 쓸 만하다.
(3 - 2) 트랜잭션 격리 수준에 따라 발생할 수 있는 문제
(4) Durability (영구성)
- 성공적으로 완료된 트랜잭션의 결과는 영구적으로 반영되어야 한다.
- DB나 시스템 장애가 발생해도 원 상태로 복구하는 회복 기능이 있어야 한다.
- DB는 이를 위해 체크섬, 저널링, 롤백 등의 기능을 제공한다.
- 체크섬 : 중복 검사의 한 형태. 오류 정정을 통해 송신된 자료의 무결성을 보호
- 저널링 : 파일 또는 DB 시스템에 변경 사항을 커밋하기 전에 로깅. 트랜잭션 등 변경 사항에 대한 로깅
3. Commit & Rollback
Commit
- 트랜잭션 작업이 성공적으로 끝났고 DB가 다시 일관된 상태에 있을 때, 이 트랜잭션의 갱신 연산이 완료된 것을 트랜잭션 관리자에 알려주는 연산
- 트랜잭션 단위로 수행되며 변경된 내용이 모두 영구적으로 저장됨
Rollback
- 트랜잭션 처리가 비정상적으로 종료되어 일관성이 깨질 때, 트랜잭션이 행한 모든 연산을 취소하는 연산
4. 트랜잭션 전파
- 트랜잭션은 커넥션 단위로 수행되므로, 커넥션 객체를 넘겨 수행해야 함.
- 트랜잭션 관련 메서드를 하나의 트랜잭션에 묶이도록 하는 것을 트랜잭션 전파라 한다.
- 스프링에서는
@Transactional
애노테이션으로 여러 쿼리 코드를 하나의 트랜잭션으로 처리함