Spring事务中requires_new和nested传播的区别

102

我不太理解 PROPAGATION_REQUIRES_NEWPROPAGATION_NESTED 传播策略之间的行为差异。在我看来,这两种方式都会回滚当前进程但不会回滚整个事务。有什么线索吗?


7
请参考这个链接:http://forum.springsource.org/archive/index.php/t-16594.html -- Juergen Hoeller 很好地解释了它。 - Ralph
@Ralph:谢谢,这正是我在寻找的。你应该将它添加为答案。 - Alexis Dufrenoy
1
@Ralph:太好了,那将是最佳答案。 - Nandkumar Tekale
1
因此,嵌套事务策略的主要区别在于,事务可以回滚到当前原子操作的开始,这与requires_new策略相同,但它只会在整个过程结束时提交,这与requires_new策略完全不同,后者在每个原子操作结束时都会提交。 - Alexis Dufrenoy
在我看来,这个差异实际上更清晰。但是,REQUIRED和NESTED这两个行为类似的关键字却很令人困惑。它们在能力方面有一些不同,比如savePoints。 - webyildirim
2
@Ralph,很不幸,您的链接不再指向现有页面:( - knittl
3个回答

144

请参阅此链接:PROPAGATION_NESTED与PROPAGATION_REQUIRES_NEW的区别? Juergen Hoeller 很好地解释了它。

PROPAGATION_REQUIRES_NEW会为给定范围启动一个新的、独立的“内部”事务。这个事务将完全独立于外部事务,具有自己的隔离范围、锁集等,在内部事务开始时挂起外部事务,在内部事务完成后恢复外部事务。

另一方面,PROPAGATION_NESTED会启动一个“嵌套”的事务,它是现有事务的真正子事务。在嵌套事务开始时,将保存一个保存点。如果嵌套事务失败,我们将回滚到该保存点。嵌套事务是外部事务的一部分,因此它只能在外部事务结束时提交。


1
好的回答和好的问题。你的评论和以下链接对我非常有用:http://www.byteslounge.com/tutorials/spring-transaction-propagation-tutorial - yaki_nuka
你在 propagation_requires_new 中描述的行为是正确的吗?因为我检查了一下,它会回滚两个事务。 - eatSleepCode
请澄清外部事务行为,如果嵌套事务失败会怎样?反之亦然。 - gstackoverflow
那么,对于嵌套事务而言,当内部事务回滚时,外部事务会在保存点继续执行,而当外部事务回滚时,所有操作都将被回滚,对吗? - Wecherowski
有任何行为上的差异吗? - gstackoverflow
1
这个Spring参考文档非常详细地解释了它: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/data-access.html#tx-propagation - bluelurker

20

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

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

请查看Spring文档


3
是的,我理解它们之间的潜在差异,但我看不出它们的行为上将有什么不同:在其中一种情况下,我会将其回滚到上一个保存点,而在另一种情况下,我会回滚当前事务而不是外部事务,但实际上,在这两种情况下,我都将回滚到当前原子操作的开头并从该点重新开始。 - Alexis Dufrenoy
1
@Traroth:@Ralph提供的链接中的两行代码可以说明它们之间的区别。PROPAGATION_REQUIRES_NEW:外部事务将在内部事务开始时被挂起,并在内部事务完成后恢复。每个内部事务在完成时都会提交/回滚。PROPAGATION_NESTED:嵌套事务是外部事务的一部分,因此只有在外部事务结束时才会提交。 - Nandkumar Tekale
我同意,所以我建议他将他的评论转化为答案。 - Alexis Dufrenoy
1
@Traroth:我同意你的观点。 :) 他的回答是最好的。 - Nandkumar Tekale

-5
请找出它们之间的不同之处。
1.) Use of NESTED Transaction

如果当前存在事务,则在嵌套事务中执行,否则像PROPAGATION_REQUIRED一样行为。 Spring支持嵌套事务

2.)使用REQUIRED事务 支持当前事务,如果不存在则创建一个新事务。 这意味着对于银行领域的取款、存款、更新事务。

3.)使用REQUIRES_NEW事务 创建一个新事务,并挂起当前事务(如果存在)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接