Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring AOP : Replace XML with annotations for transaction management?

I would like to know if it's possible to replace this code :

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="get*" read-only="true" />  
        <tx:method name="saveFile" isolation="SERIALIZABLE" propagation="REQUIRED" no-rollback-for="BusinessException" />
        <tx:method name="*" />
    </tx:attributes>
</tx:advice>

<!--Transaction aspect-->
<aop:config>
    <aop:pointcut id="businessOperation"
        expression="execution(* com.application.app.business.*.*(..)) || execution(* com.application.app.logic..*.*(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="businessOperation" />
</aop:config>   

With full annotations and no XML at all? I mean defining an aspect doing the same thing on the transaction manager.

I am able to define an aspect and pointcut but I don't see how I could get and act on the transaction manager.

Thanks in advance for your answers.

like image 205
Jeff Andrews Avatar asked Jul 17 '26 07:07

Jeff Andrews


1 Answers

What the <tx:advice /> does is basically register a TransactionInterceptor which gets the PlatformTransactionManager injected and setup with different rules for the <tx:method /> elements.

To replicate this something like the following should be done in Java based configuration.

@Bean
public TransactionInterceptor transactionInterceptor(PlatformTransactionManager transactionManager) {
    return new TransactionInterceptor(transactionManager, transactionAttributeSource());
}

@Bean
public NameMatchTransactionAttributeSource transactionAttributeSource() {
    NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource();
    RuleBasedTransactionAttribute gets = new RuleBasedTransactionAttribute();
    gets.setReadOnly(true);

    RuleBasedTransactionAttribute saveFile = new RuleBasedTransactionAttribute(8, Collections.singletonList(new NoRolebackRuleAttribute(BusinessException.class);

    Map<String, AttributeSource> matches = new HashMap<>();
    matches.put("get*", gets);
    matches.put("saveFile", saveFile);
    return tas;
}

Now the next part is that you need to define the point cuts manually. For this you need to construct an AspectJExpressionPointcutAdvisor. This is also what is done by the <aop:pointcut /> tag.

@Bean
public AspectJExpressionPointcutAdvisor transactionAdvisor(TransactionInterceptor advice) {
    AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
    advisor.setAdvice(advice);
    advisor.setExpression("execution(* com.application.app.business.*.*(..)) || execution(* com.application.app.logic..*.*(..))");
    return advisor;
}

That should be what you need to do if you want to replicate the xml configuration. However I would suggest moving to @Transactional instead, which is a lot easier to setup.

like image 181
M. Deinum Avatar answered Jul 20 '26 20:07

M. Deinum



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!