开发者

Annotation-based and xml-based transaction definitions precedence

I couldn't find a definitive answer to this in the docs, and although there seems to be a logical answer, one can't be sure. The scenario is this - you have a xml-based transaction definition, like:

<tx:advice id="txAdvice" transaction-manager="jpaTransactionManager">
    <tx:attributes>
        <tx:method name="*" propagation="REQUIRED" />
    </tx:attributes>
</tx:advice>

Which advises all service methods. But then you have @Transactional on a concrete class/method, where you want to override the propagation attribute.

It is clear that @Transactional at method-level overrides the same one at class-level, but does it override the开发者_运维问答 <tx:advice> (and actually, the <aop:pointcut>)?

I hope two interceptors won't be created on the same class, (and whichever happens to be first will start the transaction)


Thanks to skaffman for his effort. Finally I think I got the behaviour:

  1. Both <aop:advisor> and @Transactional (together with <tx:annotation-driven>) create a TransactionInterceptor around the target class (the one, whose methods are to be run in transaction).
  2. The advice with a lower order attribute overrides the other one. If no order attribute is specified, the order is undefined. But my tests showed that the one defined latest in the applicationContext.xml takes precedence, although this might not be the case always:

When two pieces of advice defined in different aspects both need to run at the same join point, unless you specify otherwise the order of execution is undefined.

At least this is the behaviour for spring 2.5.6.


After a bit of digging, I think the answer lies in TxAdviceBeanDefinitionParser.doParse. The logic says:

if <tx:attributes> is present then
   parse <tx:attributes> 
else
   instantiate an AnnotationTransactionAttributeSource to determine TX attributes

Given the only thing that reads @Transactional is AnnotationTransactionAttributeSource, that strongly suggests to me that <tx:advice> will consult @Transactional if and only if <tx:attributes> is not specified, so no overriding is possible.

This does seem to contradict Spring's usual "principle of least surprise" approach, since like you I would have expected the annotation to take precedence on a per-class or per-method basis. I would file an issue on their JIRA to get this behaviour changed.

Having said all that, I still think it's worth giving this a try to see what it does, since it may work by some other mechanism.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜