Announcement Announcement Module
Collapse
No announcement yet.
'order' setting on Transaction Advice doesn't work Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 'order' setting on Transaction Advice doesn't work

    Hi friends, I've got a problem of setting order of advice, please help me out. Thanks in advance.

    Spring version: spring-xxx-3.1.0.RELEASE

    My requirement is add an advice to handle some logic right before the transaction completes(rollback or commit), and I tried to implement it through setting 'order', a sample about 'profiler' is shown in the manual over here, but the result was not expected.

    To support transaction, I use @Transactional on the target operation:
    Code:
        @Transactional(rollbackFor=RuntimeException.class)
        public void tryDoingSth(boolean failIt) {
            System.out.println("in tryDoingSth() isSynchronizationActive = " + 
                    TransactionSynchronizationManager.isSynchronizationActive());
            //some db update/insert here
            if (failIt) {
                throw new RuntimeException("going to rollback");
            }
            System.out.println("Nothing to rollback, ready to commit.");
        }
    setting in spring 'applicationContext.xml', tx advice ordered to '2':
    Code:
    <tx:annotation-driven transaction-manager="txManager" order="2"/>
    Here is the custom advice to be ordered before transaction commit/rollback, which is ordered to '10':
    Code:
    @Component
    @Aspect
    public class TestTxAspect implements Ordered {
        @Override
        public int getOrder() {
            return 10;
        }
        
        @Around("tryDoingSth()")
        public void flag(ProceedingJoinPoint pjp) {
            System.out.println("begin of flag()");
            try {
                pjp.proceed();
            } catch (Throwable ex) {
                ex.printStackTrace();
            }
            System.out.println("at the end of flag() isSynchronizationActive = " + 
                    TransactionSynchronizationManager.isSynchronizationActive());
        }
        
        @Pointcut("execution(/* target method */)")
        public void tryDoingSth() {}
    }
    As the Spring-AOP manual states, "On the way out from a join point, the highest precedence advice runs last", so by right, when tx advice order=2 & TestTxAspect order=10, the program will go into TransactionInterceptor first then TestTxAspect, and on completion, leave through TestTxAspect first then TransactionInterceptor. But---it is not going to happen. The fact is, no matter how u set the 'order' in the <tx:annotation-driven> tag, TransactionInterceptor is always the highest priority one and of course always the first advice to be touched when a method completing its execution. But if u create another custom aspect, with an order say 9, it just works in the correct order compare to TestTxAspect's.

    The 'profiler' sample on the manual just works fine because it already sets tx advice the highest priority, if they switch the order (1 <-> 200), I bet it still work exactly the same as it did before.

    Anything else I missed?
Working...
X