我有一个方法调用链,其中A调用B调用C调用D.A和D具有@Transactional注释。但B和C没有。这种情况下交易界限的范围是什么。是B和C部分的交易吗?Spring事务边界扩展
回答
默认情况下,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。这是一个非常简单的阅读。
这取决于@Transactional
注释的propagation参数。
默认情况下,A内发生的所有事情都是单个事务的一部分 - 包括直接或间接调用的所有方法。
其他传播模式将允许D暂停当前事务并自行启动,在嵌套事务中执行,或抛出异常,因为它并不意味着在现有事务中使用。
我的意思是,当B和C没有任何注释时,是否应用默认的“需要”或...? – meisam 2011-05-18 14:58:43
在事务设计中有一条“简单”的经验规则:启动事务的对象/方法也负责确定结果(提交/回滚)。在你的情况下,A在A完成之前调用B - > C - > D,因此它们参与A的事务。由于B&C没有注释,因此它们不是交易意识。 D有点不同,默认情况下它会检查是否有活动事务并参与。否则,它会开始一个新的。 – 2011-05-18 15:06:33
@meisam:你看错了方向。事务不知道方法,而只知道如何访问事务感知资源,如数据库。该注释使A在执行事务之前启动一个事务,之后每次访问该线程中发生的事务感知资源(无论在哪种方法中)都是事务的一部分,直到A完成并提交或回退事务为止。 – 2011-05-18 15:34:07
如果您从@Transactional A调用B和C,它们仍将处于事务中。
在spring文档中查看transaction propagation。
独立的会发生什么:
,如果这个问题甚至出现时,你可能有严重的设计问题。
在95%的情况下,事务划分应该在应用程序的入口点进行,即在内部调用所有其他代码的服务方法中。
唯一有效的情况下,我可以想到@Transactional
方法调用另一个方法时,内部方法有传播REQUIRES_NEW
。如果不是这样:重构您的设计,以便您的代码只通过一个@Transactional
注释。
我同意100%。内部方法可能需要@Transactional的另一种情况是检查事务处于活动状态(TRX_MANDATORY):如果未找到任何异常,则会引发异常。我们在DAO上执行此操作,因此您无法直接调用DAO,必须通过服务层(REQUIRES_NEW | REQUIRED)。 – 2011-05-18 15:09:29
@Patrick我同意TRX_MANDATORY,这是唯一的TX注释是有道理的一个DAO – 2011-05-18 15:12:04
我不同意。如果C向队列添加任务会怎么样?那个任务实际上执行D?在这种情况下,您不能在同一个事务中使用它们,并且您需要为D使用REQUIRES_NEW,尽管这不像调用DAO方法那样直接。 – meisam 2011-05-18 16:06:39
- 1. 扩展器边界重叠
- 2. 扩展边界向外DIV
- 3. UIButton的扩展边界?
- 4. 休眠事务边界
- 5. Akka流和事务边界
- 6. cartopy - set_extent()扩展请求边界
- 7. 如何扩展插件边界QTabWidget
- 8. 稍微扩展Google Map上的边界
- 9. Android:扩展小部件和画布边界 - 扩展Button
- 10. Spring @Transactional边界
- 11. 如何扩展div来补偿去除边界div的边距?
- 12. 阻止边界扩展为边距/填充
- 13. Spring Bean扩展
- 14. Spring - 扩展StartupInfoLogger
- 15. 如何调试CMT事务边界?
- 16. 与ActiveRecord的分布式事务边界
- 17. NewRelic Java API和事务边界
- 18. Google Maps v3 API扩展界限map.fitBounds无法扩展界限
- 19. EJB 3事务边界:调用非事务性类
- 20. 扩展流畅的界面
- 21. 使用事件扩展角度服务
- 22. 扩展摆动JComboBox以移除不需要的边界
- 23. 扩展的UIButton边界最初未绘制
- 24. 如何使用JavaScript将选择扩展到单词边界?
- 25. Python的列表扩展与随机元素保持边界/原
- 26. 如何计算扩展器的边界框?
- 27. 为什么这个边界对象不能被扩展?
- 28. 图片扩展了我的容器边界
- 29. UIViewController容器视图内容扩展容器边界
- 30. 如何扩展一个类的边界而不是其他类
a)A,B,C,D在同一班级吗? b)您是否使用JDK代理(默认),CGLib(proxy-target-class = true)或AspectJ(mode = aspectj) – 2011-05-18 14:54:19
否,它们处于不同的类别中。我使用默认配置的Spring。 – meisam 2011-05-18 16:02:36
re默认配置:这取决于你的类是否支持接口。他们? – 2011-05-18 17:12:06