데이터베이스의 상태를 변화시키기 해서 수행하는 작업의 단위를 뜻한다.
즉SQL
를 이용하여 데이터베이스를 접근 하는 것을 의미한다.• SELECT
• INSERT
• DELETE
• UPDATE작업 단위는 각각의 질의어 한 문장을 의미하는 것은 아니다.
만약 블로그에 글을 올릴 때insert
문을 사용하여 데이터를 저장하고select
문으로 즉시 최신정보로 업데이트 되는 상황이라고 가정 해보자이때의 작업 단위는 insert문과 select문 둘을 합친 것이고 하나의
transaction
이라고 한다.개발자는 이
transaction
설계를 잘하는 것이 데이터를 다룰 때 이점이 많다.
Transaction의 연산에는 Commit과 Rollback 연산이 있다.
- Commit :
transaction
의 모든 연산이 완전히 수행되서 DB에 영원히 지속적으로 기록 되는 것- Rollback :
transaction
이 아예 수행한 적이 없을 때로 돌리는 것
Tranaction의 기본 특성 (ACID properties)
1. Atomicity (원자성)
: 실행이 되면 끝까지 다 되든지 아예 안하든지
(All or Nothing)2. Consistency preservation 일관성(일치성)
: 연산 결과랑 데이터 베이스가 항상 일관성 있게3. Isolation (고립성)
: 다른 transaction에 영향을 받으면 안된다.4. Durability or permanency (영속성, 지속성)
: transaction이 정상적으로 commit되면 무슨 일이 있어도 그 결과는 계속 DB에 존재
데이터베이스는 다수의 사용자들이 동시에 접근하는 경우가 빈번하게 발생하기 때문에 Concurrency Control
(동시성제어)를 DBMS에서 제공하고 있다.
Concurrency
는 transaction들이 순차적으로 실행되는 것이 아니라, transaction을 구성하는 각각의 query문들이 transaction의 순서에 상관없이 동시에 실행되는 것을 의미한다.
Concurrency에서 Transaction의 발생 가능한 문제들
1. Lost update
: T1에서 계산된 값이 T2에서 계산된 값으로 overwriting이 되서 T1의 값이 사라지게 될 때2. Temporary update (or Dirty read) : Cascading rollback
: commit되지 않은 값을 어떤 T가 가져다가 사용하게 되는 문제
만약 rollback이 된다면 존재하지 않는 dirty data를 가지고 있게 됨3. Incorrect summary (or Phantom Read, Inconsistency)
: 어떤 값에 대한 연산이 아직 남아있는데 중간에 어떤 T가 개입하여 그 old value를 임의로 commit을 해서 전혀 다른 값을 가지고 남은 연산을 하게 되는 것4. Unrepeatable read
: 같은 변수를 두 번 읽기만 했을 때 값을 수정 하지도 않았는데 어떤 T로 인해 서로 다른 값이 읽히는 것
Spring에서는 Transaction 처리를 지원 하는데
그 중 어노테이션 방식으로 @Transactional을 선언하여 사용하는 방법이 일반적이며,
선언적 Transaction이라 부른다.클래스, 메서드위에 @Transactional 이 추가되면, 이 클래스에 Transaction 기능이 적용된
Proxy 객체가 생성된다.
이 Proxy 객체는 @Transactional이 포함된 Method가 호출 될 경우, PlatformTransactionManager를 사용하여 Transaction을 시작하고,
정상 여부에 따라 Commit 또는 Rollback 한다.
Spring에서 Concurrency을 가진 다중 transaction 문제를 방지하기 위한 속성들
1. Isolation level
- Read uncommitted (level 0)
: commit 되기 전에도 데이터 읽기를 허용한다.
(Dirty read, unrepeatable read, phantom) 발생 가능- Read committed (level 1)
: commit 된 후에만 데이터 읽기를 허용한다.
(unrepeatable read, phantom)발생 가능- Repeatable read (level 2)
: Transaction이 완료될 때까지 간섭을 하지 못하게 막는다.
(phantom)발생 가능- Seriablizable (level 3)
: 강한 제약Level이 올라갈수록 격리 수준이 높아 지지만 성능저하 우려가 있다.
그래서 종종 default로
Read committed
로 설정 되어 있음
2. Propagation (전파 옵션)
- Required (default)
: 미리 시작된 transaction이 있으면 참여하고 없으면 새로 시작한다.- Support
: 미리 시작된 transaction이 있으면 참여하고 없으면 transaction 없이 시작한다.
// 간단한 데이터 조회- Mandatory
: 미리 시작된 transaction이 있으면 참여하고 없으면 예외를 발생 시킨다.
// 항상 종속되어 실행- Requires_new
: 항상 transaction을 새로 시작하고 이미 진행중인 transaction은 보류 시킨다.- Not supported
: 미리 시작된 transaction이 있으면 보류시키고 transaction을 사용 못하게 함- Never
: 미리 시작된 transaction이 있으면 예외를 발생 시키고 transaction을 사용 못하게
강제함- Nested
: 미리 시작된 transaction이 있으면 중첩 transaction을 시작한다. (부모 -> 자식)
3. ReadOnly
- 쓰기 작업이 일어나는 것을 방지
- 읽기 전용으로 설정해서 성능을 최적화
Transaction을 읽기 전용으로 설정하고
만약 쓰기 작업을 하면 예외가 발생함
4. Rollback, Commit 예외
Spring에서 어노테이션 방식으로 @Transactional을 사용하는 선언적 transaction은
런타임 예외가 발생하면 Rollback하고
예외가 발생하지 않거나 Checked Exception이 발생하면 commit한다.
Rollback 대상인 런타임 예외를 commit 대상으로 지정하기 위해서는
noRollbackFor
또는noRollbackForClassName
을 이용할 수 있다.
Ex) @Transactional(noRollbackFor=Exception.class)반대로 commit 대상인 컴파일 예외를 Rollback으로 대상을 변경하려면
각각rollbackFor
또는rollbackForClassName
으로 지정할 수 있다.
Ex) @Transactional(rollbackFor=Exception.class)
--- Checked Exception이 Rollback이 안되는 이유 ---
컴파일 시 예측/처리 가능한 예외의 처리를 개발자에게 강제하기 위해
Checked Exception
은 스프링에서 제공하는 Transaction에서의 Rollback 기본 정책에
포함되지 않는다. 때문에, 직접 규칙을 추가해야 한다.
5. Timeout
지정한 시간 내에 해당 method 수행이 완료되지 않은 경우 rollback 수행.
-1일 경우 timeout 발생 안함 (default=-1)
Ex) @Transactional(timeout=10)