You will be fine

<토비의스프링> 6.7~6.8 트랜잭션 어노테이션

by BFine
반응형

6.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. 타깃 메소드
  2. 타깃 클래스
  3. 선언 클래스
  4. 선언 타입

  순서에 따라서 적용됐는지 차례로 확인후 가장먼저 발견되는 속성정보를 사용

- 정책 예

[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

 

Transactional Annotations: Spring vs. JTA | Baeldung

A quick and practical comparison of various @Transactional annotations.

www.baeldung.com

 

반응형

블로그의 정보

57개월 BackEnd

BFine

활동하기