我在文档中找不到明确的答案,尽管似乎有一个合乎逻辑的答案,但人们无法确定。方案是这样的 - 您有一个基于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>
)吗?
我希望不会在同一个类上创建两个拦截器(并且无论哪个首先都会启动事务)
答案 0 :(得分:4)
感谢斯卡弗曼的努力。最后我想我得到了这个行为:
<aop:advisor>
和@Transactional
(以及<tx:annotation-driven>
)在目标类周围创建TransactionInterceptor
(其方法将在事务中运行)。 order
属性较低的建议会覆盖另一个属性。如果未指定order属性,则订单未定义。但是我的测试显示applicationContext.xml
中最新定义的那个优先,尽管可能并非总是如此:当在不同方面定义的两条建议都需要在同一个连接点运行时,除非您另行指定,否则执行顺序是未定义的。
至少这是春天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上提出一个问题,以便改变这种行为。
说了这么多之后,我仍然认为值得尝试看看它的作用,因为它可能会通过其他机制起作用。