토비의 스프링 3.1 책을 읽으며 일부분을 정리한 내용입니다. 
개념 이해를 위한 내용들 중 일부분을 정리했으므로 이해를 돕기위한 예시 코드들 및 자세한 전체적인 내용은 책을 통해 확인하시길 바랍니다.
포스팅 내용이 저작권의 문제가 발생할 경우 게시물은 바로 삭제/비공개 처리됩니다.

트랜잭션 속성

public Object invoke(MethodInvocation invocation) throws Throwable {
    TransactionStatus status = this.transactionManager.getTransaction(new DefaultTransactionDefinition());
    
    try {
        Object ret = invocation.proceed();
        this.transactionManager.commit(status);
        return ret;
    } catch(RuntimeException e) {
        this.transactionManager.rollback(status);
        throw e;
    }
}

 

DefaultTransactionDefinition이 구현하고 있는 TransactionDefinition 인터페이스는

트랜잭션의 동작방식에 영향을 줄 수 있는 4가지 속성 정의

1. 트랜잭션 전파

트랜잭션의 경계에서 이미 진행 중인 트랜잭션이 있을 때 또는 없을 때 어떻게 동작할 것 인가를 결정하는 방식

 

PROPAGATION_REQUIRED

진행 중인 트랜잭션이 없으면 새로 시작하고, 이미 시작된 트랜잭션이 있으면 이에 참여한다.

RPOPAGATION_REQUIRES_NEW

항상 새로운 트랜잭션을 시작

PROPAGATION_NOT_SUPPORTED

진행 중인 트랜잭션이 있어도 무시

->여러 메소드 동작시 특정 메소드만 트랜잭션 적용을 제외시키기 위해 사용

 

2. 격리 수준

서버환경에서는 여러 개의 트랜잭션이 동시에 진행될 수 있으므로 DB 트랜잭션은 격리수준을 갖고 있어야 한다. 

적절한 격리수준을 조정해서 가능한 여러 트랜잭션을 동시에 진행하면서 문제가 발생하지 않는 제어가 필요
기본적으로 DB에 설정되어 있지만 DataSource 등에서 재설정 가능

DefaultTransactionDefinition에 설정된 격리수준은 ISOLATION_DEFAULT
->DataSource에 설정되어 있는 디폴트 격리수준을 그대로 따른다는 뜻

3. 제한 시간

트랜잭션을 수행하는 제한 시간

DefaultTransactionDefinition의 기본 설정은 제한시간 x

제한시간은 트랜잭션을 직접 시작할 수 있는 PROPAGATION_REQUIRED나 RPOPAGATION_REQUIRES_NEW와 함께 사용해야만 유의미

4. 읽기 전용

트랜잭션 내에서 데이터 조작하는 시도 방지

 

 

TransactionInterceptor

스프링에서 제공하는 트랜잭션 경계설정 어드바이스

프로퍼티

PlatformTransactionManager

Properties 타입의 transactionAttributes

네 가지 기본 항목을 정의한 TransactionDefinition 인터페이스

+ rollbackOn() 메서드를 가지고 있는TransactionAttribute 인터페이스

rollbackOn() 메서드는 롤백을 수행할 예외상황을 결정하는 메서드

메서드 패턴을 키로, 트랜잭션 속성을 값으로 

 

메서드 패턴

  • ROPAGATION_NAME : 필수항목, PROPAGATION_ 으로 시작
  • ISOLATION_NAME : 생략가능, ISOLATION_으로 시작
  • readOnly : 생략가능, 읽기전용
  • timeout_NNNN : 생략가능, 제한시간 지정. NNNN은 초단위로 지정
  • -Exception1 : 한 개 이상 등록가능, 체크 예외중 롤백 대상으로 추가할 것
  • +Exception2 : 한 개 이상 등록가능, 런타임이지만 롤백되지 않을 예외 지정

트랜잭션 속성 정의 예시

    <bean id="transactionAdvice" 
              class="org.springframework.transaction.interceptor.TransactionInterceptor">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="transactionAttributes">
            <props>
                <prop key="get*">PROPAGATION_REQUIRED,readOnly,timeout_30</prop>
                <prop key="upgrade*">PROPAGATION_REQUIRES_NEW,ISOLATION_SERIALIZABLE</prop>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>

TransactionInterceptor는 2가지 예외 처리 방식 제공

1. 런타임 예외의 경우 트랜잭션은 롤백

2. 체크 예외를 던지는 경우 비즈니스 로직에 따라 개발자가 의도한 예외라 해석하고 트랜잭션을 커밋

 

위 2가지 상황에 부합하지 않는 예외는 rollbackOn() 메서드 활용

 

tx 네임스페이스

TransactionInterceptor 타입의 어드바이스 빈과 TransactionAttribute 타입의 속성 정보도 tx 스키마의 전용 태그를 이용해 정의 가능

 

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                            https://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/aop
                            http://www.springframework.org/schema/aop/spring-aop.xsd
                            http://www.springframework.org/schema/tx
                            http://www.springframework.org/schema/tx/spring-tx.xsd">

         ...
    <tx:advice id="transactionAdvice", transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" /*속성들*/ />
                        <tx:method name="upgrade*" propagation="..." isolation="SERIALIZABLE"/>
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>

 

포인트 컷과 트랜잭션 속성의 적용 전략

  1. 트랜잭션 포인트컷 표현식은 타입 패턴이나 빈 이름을 이용
    • 트랜잭션을 적용할 타깃 클래스의 메서드는 모두 트랜잭션 적용 후보
    • 읽기 전용 메서드도 트랜잭션 적용
    • execution() 방식의 포인트컷 대신 bean() 표현식을 사용하는 것도 고려
  2. 공통된 메서드 이름 규칙을 통해 최소한의 트랜잭션 어드바이스와 속성을 정의
    • get, find와 같이 조회전용 메서드의 접두어를 정해두기
  3. 프록시 방식 AOP는 같은 타깃 오브젝트 내의 메서드를 호출할 때는 적용되지 않는다.

 

트랜잭션 속성 적용

1. 트랜잭션 경계설정의 일원화

트랜잭션 경계설정 부가기능을 다양한 계층에서 중구난방으로 적용하는 것은 좋지 않다.

일반적으로 서비스 계층 오브젝트 메서드가 가장 적절

서비스 계층을 트랜잭션 경계로 정했다면, DAO에 직접 접근은 지양

 

2. 서비스 빈에 적용되는 포인트컷 표현식 등록

포인트컷 표현식을 비즈니스 로직의 서비스 빈에 적용되도록 작성

 

3.트랜잭션 속성을 가진 트랜잭션 어드바이스 등록

TransactionInterceptor를 tx:advice 태그를 이용해 등록하고, attributes를 잘 정의

+ Recent posts