Transaction
데이터의 상태를 변화시키는 작업의 단위이며, 아래의 성질을 가진다.
- 원자성(Atomicity) - 하나의 transaction 내에서 실행한 작업들은 하나로 간주단다. 모두 성공 또는 실패를 의미한다.
- 일관성(Consistency) - 일관성 있는 상태를 유지한다.
- 격리성(Isoloation) - 동시에 실행되는 transaction들은 서로 영향을 미치지 않도록 해야한다.
- 지속성(Durability) - transaction을 성공적으로 마치면 결과가 항상 저장돼야 한다.
Spring Transactional
- 선언적 transaction으로, @Transactional annotation을 class/method에 선언하여 사용한다.
- 선언된 transaction이 적용된 Proxy객체가 생성되고, 해당 class/method가 호출되면 PlatformTransactionManager를 사용하여 transaction이 begin/commit/rollback된다.
왜 필요한가
- transaction begin, commit을 자동으로 수행한다.
- 예외가 발생하면 rollback 처리를 자동으로 수행한다.
속성
isoloation
- Default
- db의 isloation level을 다른다. innodb의 경의 repeatable-read
- Read Committed
- transaction commit된 값만 읽는다.
- dirty read 방지
- Repeatable Read
- transaction이 완료될때까지 해당 영역의 데이터는 수정 불가하다.
- 선행 transaction이 종료될 때까지 후행 transaction은 데이터 갱신이 불가하다.
- Non Repeatable Read 방지
- Serializable
- MVCC를 사용하지 않는다.
- transaction이 완료될때까지 모두 shared lock을 건다.
- Phantom read 방지한다.
propagation
transaction 도중 다른 transaction을 실행하는 상황에 선택하는 옵션이다.
- required
- default
- 부모 transaction없으면, 새로운 transaction을 생성한다.
- 있으면, 그 transaction에 흡수된다.
- supports
- 이미 시작된 transaction이 있으면 참여한다.
- 없으면 transaction없이 진행한다.
- requires_new
- 부모 transaction을 무시하고, 새로운 transaction을 생성한다.
- 이미 진행중인 것이 있으면 잠시 보류한다.
- mandatory
- 부모 transaction이 있으면 참여한다.
- 없으면 예외가 발생한다.
- 혼자서 독립적으로 transaction을 진행하면 안 되는 경우에 사용한다.
- never
- transaction을 사용하지 않도록 강제화한다.
- 이미 진행중인 transaction도 존재하면 안된다. 있으면 예외가 발생한다.
- nested
- 이미 진행중인 transaction이 있으면, 중첩 transaction을 실행한다.
- transaction안에 다시 transaction을 생성한다.
- 자식의 commit/rollback은 부모에게 영향을 안주지만, 부모의 commit/rollback은 자식에게 영향을 준다.
readonly
- transaction을 읽기 전용으로 설정한다.
- 보통 최적화를 위해 사용한다.
- 쓰기 작업을 의도적으로 방지할 수 있고, 데이터 갱신 작업이 발생하면 예외가 발생한다.
rollbackfor
- runtime 예외가 발생하면 rollback한다. 아니면 commit.
- rollbackFor : 특정 예외가 발생하면 강제로 rollback
- noRollbackFor : 특정 예외가 발생해도 rollback 발생하지 않는다.
timeout
- 지정한 시간 내에 수행이 완료되지 않으면, rollback 수행한다.
주의사항
다수의 transaction이 경쟁할 때 발생할 수 있는 문제점들
- Dirty Read
- transaction a : A의 값을 1 -> 2로 변경. commit은 아직.
- transaction b : A의 값을 읽음. 2로 읽음
- transaction a : rollback
- transaction b : 잘못된 값을 읽음
- Non-Repetable Read
- transaction a : A의 값, 1을 읽음
- transaction b : A의 값을 1 -> 2로 변경. commit함
- transaction a : 1번과 동일한 transaction에서 A의 값을 다시 읽음. 2로 읽음
- transaction a는 동일한 transaction에서 A의 값을 다르게 읽었다.
- Phantom Read
- transaction a : A조건의 범위 1 ~ 5 값을 읽음
- transaction b : A조건의 범위에 6 ~ 8 을 추가
- transaction a : 1번과 동일한 transaction에서 A조건의 범위를 읽음. 1 ~ 8로 다른 값이 조회됨.
Reference