基于注释和基于xml的事务定义优先级

时间:2010-01-02 09:58:25

标签: java spring

我在文档中找不到明确的答案,尽管似乎有一个合乎逻辑的答案,但人们无法确定。方案是这样的 - 您有一个基于xml的事务定义,如:

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

建议所有服务方法。但是你在具体的类/方法上有@Transactional,你要覆盖propagation属性。

很明显,方法级别的@Transactional会覆盖类级别的同一个,但会覆盖<tx:advice>(实际上是<aop:pointcut>)吗?

我希望不会在同一个类上创建两个拦截器(并且无论哪个首先都会启动事务)

2 个答案:

答案 0 :(得分:4)

感谢斯卡弗曼的努力。最后我想我得到了这个行为:

  1. <aop:advisor>@Transactional(以及<tx:annotation-driven>)在目标类周围创建TransactionInterceptor(其方法将在事务中运行)。
  2. order属性较低的建议会覆盖另一个属性。如果未指定order属性,则订单未定义。但是我的测试显示applicationContext.xml中最新定义的那个优先,尽管可能并非总是如此:
  3.   

    当在不同方面定义的两条建议都需要在同一个连接点运行时,除非您另行指定,否则执行顺序是未定义的。

    至少这是春天2.5.6的行为。

答案 1 :(得分:3)

经过一番挖掘,我认为答案在于TxAdviceBeanDefinitionParser.doParse。逻辑说:

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

鉴于@Transactional唯一的内容是AnnotationTransactionAttributeSource,我强烈建议我<tx:advice>只有@Transactional不是<tx:attributes>时才会咨询{{1}}指定,所以不可能覆盖。

这似乎与Spring通常的“最少惊喜原则”方法相矛盾,因为像我一样,我希望注释优先于每个类或每个方法。我会在他们的JIRA上提出一个问题,以便改变这种行为。

说了这么多之后,我仍然认为值得尝试看看它的作用,因为它可能会通过其他机制起作用。