REQUIRED
MANDATORY
REQUIRED_NEW
SUPPORTS
NOT_SUPPORTED
NEVER
NESTED
REQUIRED
와 동일 동작REQUIRED
, REQUIRED_NEW
전파인 경우에만 사용 가능transactionManager 별칭 반환
String value() default "";
구체적인 TransactionManager 빈 정의를 통해 사용하려고 하는 transaction manager 사용하기 위함
Qualifier value 사용
String transactionManager() default "";
각 transaction manager를 구분하는 0 이상의 라벨값
미리 지정된 값을 사용하는 방식
String[] label() default {};
트랜잭션 전파 타입
기본값은 Propagation.REQUIRED
Propagation propagation() default Propagation.REQUIRED;
새로 시작된 트랜잭션에만 적용
Propagation.REQUIRED, Propagation.REQUIRES_NEW 와만 사용 가능
Isolation isolation() default Isolation.DEFAULT;
int timeout() default TransactionDefination.TIMEOUT_DEFAULT;
String timeoutString() default "";
읽기 전용인 경우 true 로 설정 (기본값 false)
런타임에 최적화
읽기 전용으로 설정되어도 반드시 쓰기 엑세스가 실패하는 건 아님
boolean readOnly() default false;
트랜잭션 롤백 유발하는 예외유형 명시
- 트랜잭션은 기본적으로 RuntimeException (unchecked-exception)에서는 롤백됨
- Checked-exception에서는 롤백되지 않음
- checked-exception을 명시해서 롤백하도록 하는 역할
Class<? extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
트랜잭션 롤백 유발하지 않는 예외 명시
checked-exception을 명시
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
@Transaction
선언 클래스를 상속받은 서브클래스에서도 트랜잭션 적용을 위해선 서브클래스에도 따로 @Transactional
선언 필요@Transactional
선언 시 테스트 종료될 때 자동으로 롤백WebEnvironment
의 RANDOM_PORT
, DEFINED_PORT
사용 시 롤백 XAuto-Increment
옵션은 트랜잭션 범위 밖에서 동작public
메소드에만 적용CGLIB 프록시
는 동적으로 상속을 통해 프록시 생성private
메소드는 상속이 불가 → 프록시 생성 Xfinal
메소드도 상속불가므로, 프록시 생성 Xprotected
메소드도 AOP 적용되지 않음CGLIB프록시
말고 JDK 동적 프록시
경우 인터페이스 기반으로 동작결론
예제
public class AppleSeller {
public void packAll(List<Apple> apples) {
apples.forEach(apple -> pack(apple));
}
@Transactional
public void pack(Apple apple) {
bookRepository.save(apple);
}
}
이렇게 되어야 pack() 메소드 호출 시 트랜잭션이 적용된다.
내부 호출된 상황에서는 pack() 메소드를 호출해도 트랜잭션이 적용되지 않는다.
원인
Proxy를 스프링 Bean으로 등록
해결법
@Transactional
선언
좋은 글 감사합니다. 자주 올게요 :)