Spring事务边界扩展

时间:2011-05-18 14:34:59

标签: java spring transactions

我有一系列方法调用,其中A调用B调用C调用D.A和D有@Transactional注释。但B和C没有。在这种情况下,事务边界的范围是什么。 B和C是交易的一部分吗?

4 个答案:

答案 0 :(得分:5)

默认情况下,A,B,C& D在同一笔交易中工作。事务的默认传播级别为TX_REQUIRED,这意味着如果不存在新事务,则启动新事务(A启动一个,B,C,D参与)。

D可以通过将其传播级别设置为TX_REQUIRES_NEW(如果您的环境支持它)来启动新事务。在那种情况下,当D完成时,恢复暂停的事务。提交D不会影响事务A的结果。回滚A不会回滚D(已提交),因为它们是单独的事务。

此外,许多开发人员忘记了只有公共方法可能被标记为@Transactional,因为Spring使用代理来管理事务(私有/受保护的方法被调用“this” - 因此代理没有机会做它的魔法) 。如果您使用字节代码注入而不是代理,则不必如此。

如果您想了解有关交易设计模式的更多信息,我强烈建议您使用以下电子书(免费! - 需要注册):http://www.infoq.com/minibooks/JTDS。这是一个非常简单的阅读。

答案 1 :(得分:3)

这取决于@Transactional注释的propagation参数。

默认情况下,A中发生的所有事情都是一个事务的一部分 - 包括由它直接或间接调用的所有方法。

其他传播模式允许D挂起当前事务并启动它自己的事务,在嵌套事务中执行,或抛出异常,因为它不打算在现有事务中使用。

答案 2 :(得分:2)

独立于发生的事情:

如果这个问题出现了,你可能会遇到严重的设计问题。

在95%的情况下,事务划分应该在应用程序的入口点进行,即在内部调用所有其他代码的服务方法中。

我能想到的唯一有效的案例是,当一个@Transactional方法调用另一个时,内部方法有传播REQUIRES_NEW。如果不是这样:重构您的设计,以便您的代码只通过一个@Transactional注释。

答案 3 :(得分:1)

如果您从@Transactional A拨打B和C,他们仍将处于交易中。

在春季文档中查看transaction propagation