Spring事务中requires_new和嵌套传播的区别

Posted

技术标签:

【中文标题】Spring事务中requires_new和嵌套传播的区别【英文标题】:Differences between requires_new and nested propagation in Spring transactions 【发布时间】:2012-09-05 15:12:17 【问题描述】:

我无法理解 PROPAGATION_REQUIRES_NEWPROPAGATION_NESTED 传播策略之间的行为差​​异。在我看来,在这两种情况下,当前进程都是回滚的,而不是整个事务。有什么线索吗?

【问题讨论】:

看这个链接:forum.springsource.org/archive/index.php/t-16594.html -- Juergen Hoeller 解释的很好 @Ralph:谢谢,这正是我想要的。您应该将其添加为答案。 @Ralph :太好了,这将是一个最佳答案。 所以主要区别在于,使用嵌套事务策略,事务可以回滚到当前原子操作的开头,这与 requires_new 策略中相同,但只会提交在整个过程结束时,这与 requires_new 策略完全不同,其中每个原子操作将在结束时提交。 @Ralph 不幸的是,您的链接不再指向现有页面 :( 【参考方案1】:

看这个链接:PROPAGATION_NESTED versus PROPAGATION_REQUIRES_NEW?Juergen Hoeller 解释的很好。 -- Spring 源码论坛于 2019 年 2 月 28 日完全离线,但您可以在下面的引文中阅读文章的相关部分

PROPAGATION_REQUIRES_NEW 启动一个新的、独立的“内部”事务 对于给定的范围。该事务将被提交或回滚 完全独立于外部事务,拥有自己的 隔离范围,它自己的一组锁等。外部事务将 在内部的开始处被暂停,并在 内一已完成。 ...

另一方面,PROPAGATION_NESTED 启动“嵌套”事务, 这是现有交易的真正子交易。会发生什么 是在嵌套开始时将采用保存点 交易。 Í如果嵌套事务失败,我们将回滚到 那个保存点。嵌套事务是外部事务的一部分 事务,所以它只会在外部的末尾提交 交易。 ...

【讨论】:

好答案和好问题。您的 cmets 和以下链接对我非常有用:byteslounge.com/tutorials/… 您在propagation_requires_new 中描述的行为是否正确?因为当我检查它回滚两个事务。 如果嵌套事务失败,请澄清外部事务行为(它也会失败吗?),反之亦然 所以对于嵌套事务,当内层回滚时,外层会继续保存点,而当外层回滚时,所有​​操作都会回滚,对吧? 这个 Spring 参考资料解释得很详细:docs.spring.io/spring-framework/docs/current/…【参考方案2】:

请找出区别

1.) Use of NESTED Transaction

如果当前事务存在,则在嵌套事务中执行,否则行为类似于 PROPAGATION_REQUIRED。 Spring 支持嵌套事务

2.) 使用必需事务 支持当前事务,如果不存在则创建一个新事务。 .这意味着对于银行领域,例如提款,存款,更新交易

3.) 使用 REQUIRES_NEW 交易 创建一个新事务,如果存在则暂停当前事务。

【讨论】:

【参考方案3】:

PROPAGATION_REQUIRES_NEW :对每个受影响的事务范围使用完全独立的事务。在这种情况下,底层物理事务是不同的,因此可以独立提交或回滚,外部事务不受内部事务回滚状态的影响。

PROPAGATION_NESTED :使用具有多个可以回滚的保存点的单个物理事务。这种部分回滚允许内部事务范围触发其范围的回滚,尽管某些操作已回滚,但外部事务能够继续物理事务。此设置通常映射到 JDBC 保存点,因此仅适用于 JDBC 资源事务。

查看spring documentation

【讨论】:

是的,我理解下划线的区别,但我看不出它的行为会有什么不同:在一种情况下,我会将 a 回滚到上一个保存点,在另一种情况下,我将回滚当前事务而不是外部事务,但实际上,在这两种情况下,我都会回滚到当前原子操作的开头并从该点重新开始。 @Traroth :@Ralph 链接上的两行将说明行为上的差异。 PROPAGATION_REQUIRES_NEW :外部事务将在内部事务开始时暂停,并在内部事务完成后恢复。每个内部事务在完成时提交/回滚。 PROPAGATION_NESTED :嵌套事务是外部事务的一部分,因此只会在外部事务结束时提交。 我同意,所以我建议他从他的评论中做出回答。 @Traroth:我同意你的看法。 :) 他有最好的答案。

以上是关于Spring事务中requires_new和嵌套传播的区别的主要内容,如果未能解决你的问题,请参考以下文章

Spring事务隔离级别:REQUIRES_NEW使用细节

REQUIRES_NEW 如果不在一个事务那么自己创建一个事务 如果在一个事务中 自己在这个大事务里面在创建一个子事务 相当于嵌套事务 双层循环那种

Spring 事务 REQUIRED 与 REQUIRES_NEW :回滚事务

Spring 是不是真的使用 REQUIRES_NEW 启动新事务?

spring事务传播行为之使用REQUIRES_NEW不回滚

Spring事务传播行为REQUIRES_NEW和NESTED用法栗子