Spring Transaction advice : AOP proxy vs AspectJ weaving

You are using Spring Transactions with Annotations.

MyBS.methodRequired has Required propagation.

MyBS.methodRequiresNew has Requires_New propagation.

… methodRequired (…) { … methodRequiresNew(…); … }

Do you get a new transaction if you call methodRequiresNew from methodRequired?

You don’t! Not if you are using the default proxy mode via AOP proxies through which transactional advice is applied. If you move the method with the new transaction to a different class and then call it – you do get a new transaction. What’s happening here?

When proxies are used to add transactional behaviour and you call a method directly within the class, there is no proxy in between. So no transactional behaviour can be added. So only calls from ‘outside’ will use the behaviour specified by the @Transactional annotation. For ‘internal’ calls, the @Transactional annotation is silently ignored!

The ways around this that I can think of (Comments welcome if you have more suggestions):

  • Move such code to a new class. Then the calls become external. This may not be very neat depending on how your code is structured.
  • Use BeanFactoryPostProcessor and put a reference to the proxied bean into the bean. A self referring bean. Instead of calling the method directly, use the injected reference to make the call.
  • You could also just pull the proxied bean from the application context with the getBean method. But that’s Anti Dependency Injection. Not good.
  • Use AspectJ mode for transactions instead of proxy mode.

Quote from the Spring API reference docs:

Note: In proxy mode (which is the default), only ‘external’ method calls coming in through the proxy will be intercepted. This means that ‘self-invocation’, i.e. a method within the target object calling some other method of the target object, won’t lead to an actual transaction at runtime even if the invoked method is marked with @Transactional!

Consider the use of AspectJ mode (see below) if you expect self-invocations to be wrapped with transactions as well. In this case, there won’t be a proxy in the first place; instead, the target class will be ‘weaved’ (i.e. its byte code will be modified) in order to turn @Transactional into runtime behavior on any kind of method.



Tags: , , , , ,
This entry was posted on Sunday, August 22nd, 2010 at 2:53 am and is filed under Uncategorized. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

One Response to “Spring Transaction advice : AOP proxy vs AspectJ weaving”

  1. Rothmans

    Or (preffered) you could do this way
    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    @Override
    protected void doInTransactionWithoutResult(org.springframework.transaction.TransactionStatus status) {
    // …
    }
    });

Leave a Reply

Your comment