Spring Boot에서 Transaction AOP 설정하는 방법이다.
먼저 Spring MVC에서는 Transaction에 AOP를 설정하기 위해 XML을 이용하여 Tranaction AOP를 설정한다.
■transction-context.xml
<tx:annotation-driven transaction-manager="txManager"/> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="retrieve*" read-only="true" /> <tx:method name="select*" read-only="true" /> <tx:method name="insert*" rollback-for="Exception" /> <tx:method name="update*" rollback-for="Exception" /> <tx:method name="delete*" rollback-for="Exception" /> <tx:method name="save*" rollback-for="Exception" /> <tx:method name="process*" propagation="REQUIRES_NEW" rollback-for="Exception" /> </tx:attributes> </tx:advice>
<aop:config> <aop:pointcut id="requiredTx" expression="execution(* batch..service.impl.*Impl.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="requiredTx" /> </aop:config> </beans> |
Transaction Manager bean을 설정한 후 transaction advice를 이용하여 Transaction을 적용할 Method를 설정한다.
Spring Boot에서는 TransactionInterceptor와 AspectJExpressionPointcut를 이용하여 bean을 설정함으로써 Transaction을 제어할 수 있다.
■TransactionConfig.java
import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.aop.Advisor; import org.springframework.aop.aspectj.AspectJExpressionPointcut; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.interceptor.DefaultTransactionAttribute; import org.springframework.transaction.interceptor.RollbackRuleAttribute; import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute; import org.springframework.transaction.interceptor.TransactionInterceptor; @Aspect @Configuration public class TransactionConfig { private static final Logger LOGGER = LoggerFactory.getLogger(TransactionConfig.class); private static final int TX_METHOD_TIMEOUT = 3; private static final String AOP_POINTCUT_EXPRESSION = "execution(* webapp.sample.service..*.*(..))"; // @Autowired // private PlatformTransactionManager transactionManager; @Autowired private DataSourceTransactionManager transactionManager; @Bean public TransactionInterceptor txAdvice() {
TransactionInterceptor txAdvice = new TransactionInterceptor(); Properties txAttributes = new Properties();
List<RollbackRuleAttribute> rollbackRules = new ArrayList<RollbackRuleAttribute>();
rollbackRules.add(new RollbackRuleAttribute(Exception.class)); /** If need to add additionall exceptio, add here **/
DefaultTransactionAttribute readOnlyAttribute = new DefaultTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED); readOnlyAttribute.setReadOnly(true); readOnlyAttribute.setTimeout(TX_METHOD_TIMEOUT);
RuleBasedTransactionAttribute writeAttribute = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED, rollbackRules); writeAttribute.setTimeout(TX_METHOD_TIMEOUT);
String readOnlyTransactionAttributesDefinition = readOnlyAttribute.toString(); String writeTransactionAttributesDefinition = writeAttribute.toString(); LOGGER.info("Read Only Attributes :: {}", readOnlyTransactionAttributesDefinition); LOGGER.info("Write Attributes :: {}", writeTransactionAttributesDefinition);
// read-only txAttributes.setProperty("retrieve*", readOnlyTransactionAttributesDefinition); txAttributes.setProperty("select*", readOnlyTransactionAttributesDefinition); txAttributes.setProperty("get*", readOnlyTransactionAttributesDefinition); txAttributes.setProperty("list*", readOnlyTransactionAttributesDefinition); txAttributes.setProperty("search*", readOnlyTransactionAttributesDefinition); txAttributes.setProperty("find*", readOnlyTransactionAttributesDefinition); txAttributes.setProperty("count*", readOnlyTransactionAttributesDefinition);
// write rollback-rule txAttributes.setProperty("*", writeTransactionAttributesDefinition);
txAdvice.setTransactionAttributes(txAttributes); txAdvice.setTransactionManager(transactionManager);
return txAdvice; } @Bean public Advisor txAdviceAdvisor() { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression("(execution(* *..*.service..*.*(..)) || execution(* *..*.services..*.*(..)))"); pointcut.setExpression(AOP_POINTCUT_EXPRESSION); return new DefaultPointcutAdvisor(pointcut, txAdvice()); } } |
TransactionInterceptor bean 생성 시 readOnlyAttribute와 wirtheOnlyAttribute를 DefaultTransactionAttribute와 RuleBasedTransactionAttribute를 이용하여 생성한다.
Transaction Attribute에 ReadOnlyAttribute와 writeOnlyAttribute를 메소드의 유형에 따라 설정한 후 TransactionInterceptor에 정의한다.
그리고 Advisor를 bean으로 설정할 때 pointCut을 생성하여 expression을 정의한다.
'Spring Framrwork' 카테고리의 다른 글
[Spring Boot] Exception Resolver (0) | 2018.08.14 |
---|---|
[Spring Boot] Properties Configuration (0) | 2018.08.13 |
[Spring Boot] Mybatis 적용 (0) | 2018.08.13 |
[Spring Boot] Intercepor 적용 (0) | 2018.08.13 |
[Spring Boot] Filter 적용 (0) | 2018.08.13 |