스프링 Transactional
2018-10-26
스프링 Transactional
@Transactional 속성
1) isolation ( 격리 수준 / @Transactional(isolation=Isolation.DEFAULT) )
여러 트랜잭션이 진행될 때에 트랜잭션의 작업 결과를 다른 트랜잭션에게 어떻게 노출할 것인지를 결정하는 수준이다.
- DEFAULT
- DB 드라이버의 격리 레벨에 의존 (데이터베이스마다 다른다)
- READ_UNCOMMITTED (level 0)
- 가장 낮은 격리 수준이다. 하나의 트랜잭션이 커밋되기 전에 그 변화가 다른 트랜잭션에 노출되는 문제가 있다.
- 트랜잭션에 처리 중인 혹은 아직 커밋되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용한다. (dirty read 허용)
- 하지만 가장 빠르기 때문에 데이터의 일관성이 조금 떨어지더라도 성능을 극대화하기 위해 사용하기도 한다.
- READ_COMMITTED (level 1)
- 보통 데이터베이스에서 디폴트로 지원하는 격리 레벨이다. 일반적으로 가장 많이 사용된다.
- 다른 트랜잭션에 의해 커밋되지 않은 데이터는 볼 수 없다. (dirty read 방지)
- 어떠한 사용자가 데이터를 변경하는 동안 다른 사용자는 해당 데이터에 접근할 수 없다.
- 대신 하나의 트랜잭션이 읽은 로우를 다른 트랜잭션이 수정할 수 있다. 이 때문에 처음 트랜잭션이 같은 로우를 읽을 경우 다른 내용을 발견할 수도 있다.
- REPEATABLE_READ (level 2)
- 트랜잭션이 완료될 때 까지 SELECT 문장이 사용되는 모든 데이터에 shared lock이 걸리므로 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정이 불가능하다.
- 선행 트랜잭션이 읽은 데이터는 트랜잭션이 종료될 때 까지 후행 트랜잭션이 갱신하거나 삭제하지 못함으로써 같은 데이터를 두 번 쿼리했을 때 일관성 있는 결과를 리턴한다.
- 하지만 새로운 로우를 추가하는 것은 제한하지 않으므로 다른 트랜잭션이 새로운 데이터를 입력 했을 경우에는 볼 수 있다.
- SERIALIZABLE (level 3)
- 가장 높은 격리 레벨로 이름 그대로 트랜잭션을 순차적으로 진행시켜 준다.
- 여러 트랜잭션이 동시에 같은 테이블의 정보를 엑세스 하지 못하므로 성능 저하의 우려가 있다.
- 동일한 데이터에 대해 동시에 두 개 이상의 트랜잭션이 수행될 수 없다
2) propagation (전파 속성 / @Transactional(propagation=Propagation.REQUIRED) )
트랜잭션을 새로 시작하거나 기존 트랜잭션에 참여하는 방법을 결정하는 속성이다.
- PROPAGATION_REQUIRED : 디폴트 속성. 부모 트랜잭션 내에서 실행하며 부모 트랜잭션이 없을 경우 새로운 트랜잭션을 생성
- PROPAGATION_REQUIRED_NEW : 부모 트랜잭션을 무시하고 무조건 새로운 트랜잭션이 생성
- PROPAGATION.SUPPORT : 부모 트랜잭션이 있다면 부모 트랜잭션 내에서 실행. 없다면 비-트랜잭션 상태로 실행
- PROPAGATION.MANDATORY : 반드시 트랜잭션 내에서 메소드가 실행되어야 한다. 없으면 예외 발생
- PROPAGATION.NOT_SUPPORTED : 비-트랜잭션 상태로 실행하며, 부모 트랜잭션 내에서 실행될 경우 일시 정지
- PROPAGATION_NEVER : 트랜잭션을 사용하지 않도록 강제한다. 부모 트랜잭션이 있을 경우 예외 발생.
- PROPAGATION_NESTED :
- 이미 진행 중인 트랜잭션이 있으면 중첩 트랜잭션을 실행한다. 없으면 REQUIRED 처럼 동작한다.
- 중첩된 트랜잭션은 먼저 시작된 부모 트랜잭션의 커밋과 롤백에는 영향을 받지만 자신의 커밋과 롤백은 부모 트랜잭션에게 영향을 주지 않는다.
3) readOnly ( @Transcational(readOnly=true) )
- 해당 트랜잭션을 읽기 전용 모드로 처리
- 성능을 최적화 하기 위해 사용할 수도 있고 특정 트랜잭션 작업 안에서 쓰기 작업이 일어나는 것을 의도적으로 방지하기 위해 사용할 수 있다.
- 기본값 false
4) rollbackFor( @Transactional(rollbackFor=Exception.class) )
정의된 Exception에 대해서 rollback을 수행
5) noRollbackFor( @Transactional(noRollbackFor=Exception.class) )
정의된 Exception에 대해서는 rollback을 수행하지 않음
참고
HANUMOKA - Spring @Transactional 적용
프로그래밍좀비 - Spring @Transcational에 관해
꿈꾸는 태태태의 공간 - Spring Transaction 옵션
Rednics Blog - 트랜잭션 속성