<토비의스프링> 6.7~6.8 트랜잭션 어노테이션
by BFine6.7 어노테이션 트랙잭션 속성과 포인트컷
- 세밀하게 튜닝된 트랜잭션 속성을 적용해야 하는 경우도 있다.
- 포인트컷 자체가 지저분해지고 설정파일도 복잡해짐
=> 직접 타깃에 트랜잭션 어노테이션을 지정하자
6.7.1 트랜잭션 어노테이션
- @Transactional
@Target({ElementType.TYPE, ElementType.METHOD})// 대상지정
@Retention(RetentionPolicy.RUNTIME) // 정보유지 기간
@Inherited
@Documented
public @interface Transactional {
@AliasFor("transactionManager")
String value() default "";
@AliasFor("value")
String transactionManager() default "";
String[] label() default {};
Propagation propagation() default Propagation.REQUIRED;
Isolation isolation() default Isolation.DEFAULT;
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
String timeoutString() default "";
boolean readOnly() default false;
Class<? extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
}
- 사용되는 포인트컷은 TransactionAttributeSourcePoincut 이고 표현식과 같은 선정기준은 갖고있지 않다.
동작방식
---- 포인트컷 --> TransactionAttributeSourcePoincut
adviser ▼ 속성이 부여된 대상을 확인후 포인트컷
---- 어드바이스 --> TxInterceptor | AnnotationTransactionAttributeSorce
- 포인트컷과 트랜잭션 속성을 어노테이션 하나로 지정가능
- 유연한 속성 제어는 가능하지만..
=> 코드는 지저분, 동일 속성정보를 가진 어노테이션을 반복적으로 메서드마다 부여해야함
- 4단계의 Fallback 정책을 지원, 메서드의 속성을 확인할때
- 타깃 메소드
- 타깃 클래스
- 선언 클래스
- 선언 타입
순서에 따라서 적용됐는지 차례로 확인후 가장먼저 발견되는 속성정보를 사용
- 정책 예
[1] 마지막
public interface Service{
[2] 세번째
void method1();
[3] 세번째
void method2();
}
[4] 두번째
public class ServiceImpl implements Service{
[5] 첫번째 후보
void method1();
[6] 첫번째 후보
void method2();
}
- @Transactional은 먼저 타입레벨에 정의하고 공통속성을 따르지 않는 메서드만 메서드레벨에 부여
- 타깃 클래스보다는 인터페이스에 @Transactional 설정을 두는게 바람직하다
- 인터페이스를 이용하는 프록시 방식의 AOP가 아닌 트랜잭션 방식을 적용하면 무시되므로 타깃클래스에 적용
보통 타깃 메서드에 어노테이션을 사용하고 있는데...
6.7.2 트랜잭션 어노테이션 적용
- 클래스에 적용할경우 디폴트로 모든 메소드에 적용
6.8 트랜잭션 지원 테스트
6.8.1 선언적 트랜잭션과 트랜잭션 전파속성
- REQUIRED로 전파속성 지정하면 앞에 트랜잭션이 있으면 참여, 없으면 새로운 트랜잭션 시작
- DB 트랜잭션은 단위 업무와 일치해야 한다.
- AOP를 이용해 코드 외부에서 속성 지정하는 방법을 선언적 트랜잭션
트랜잭션 API를 사용해 직접 코드안에서 사용하는 방법을 프로그램 트랜잭션
- 전파속성을 단순조회라도 ReadOnly로 명시하자(성능향상)
6.8.2 트랜잭션 동기화와 테스트
- 트랜잭션 추상화 핵심은 트랜잭션 매니저와 트랜잭션 동기화이다.
- PlatformTransactionManager 인터페이스를 구현한 트랜잭션 매니저를 통해 일관된 트랜잭션 제어
- 동기화를 통해 트랜잭션 정보를 저장소에 보관해두었다가 DAO에서 공유 할수 있었다.
6.8.3 테스트를 위한 트랜잭션 어노테이션
- 통으로 테스트 클래스에 트랜잭션 관련 설정 하고싶을때 => @TransactionConfiguration
궁금했던거
Javax와 Spring의 Transactional의 차이는 뭘까?
- 자바의 Transactional
@Inherited
@InterceptorBinding
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Transactional {
public enum TxType {
REQUIRED,
REQUIRES_NEW,
MANDATORY,
SUPPORTS,
NOT_SUPPORTED,
NEVER
}
@Nonbinding
public Class[] rollbackOn() default {};
@Nonbinding
public Class[] dontRollbackOn() default {};
}
- 내부적으로 속성 설정의 차이가 있고 Spring이 좀더 세세한 설정이 가능해 보인다.
- 찾아보니 JTA(Java의 Transactional)은 자바어플리케이션이 관리하는 CDI Bean & Class 에 대해 트랜잭션
설정이 가능 하지만 Spring꺼는 오직 Spring Bean에만 적용이 가능하다.
- 물론 이슈가 없으면 Spring Transactional을 쓰자..
- CDI는 Contexts and Dependency Injection 으로 Java EE에서 Spring의 DI처럼 의존성을 주입해주는 것이다.
- 자세한 내용은 아래 사이트에 잘나와있다. https://www.baeldung.com/spring-vs-jta-transactional
'개발서적 > 토비의스프링' 카테고리의 다른 글
<토비의스프링> 7.3~7.4 서비스 추상화 (0) | 2021.02.20 |
---|---|
<토비의스프링> 7.1~7.2 SQL DAO 분리하기 (0) | 2021.02.20 |
<토비의스프링> 6.4~6.5 AOP(2) (0) | 2021.02.20 |
<토비의스프링> 6.1~6.3 AOP (0) | 2021.02.18 |
<토비의스프링> 5.1~5.2 서비스추상화 (0) | 2021.02.17 |
블로그의 정보
57개월 BackEnd
BFine