Spring事务传播性之PROPAGATION_REQUIRED

 最近学习spring的事务传播性,参考官方指南里面的原文,发现这段文字实在艰涩,摸索良久,翻译了下并记录了自己的理解。

 

PROPAGATION_REQUIRED

When the propagation setting is PROPAGATION_REQUIRED, a logical transaction scope is created for each method upon which the setting is applied. Each such logical transaction scope can determine rollback-only status individually, with an outer transaction scope being logically independent from the inner transaction scope. Of course, in case of standard PROPAGATION_REQUIRED behavior, all these scopes will be mapped to the same physical transaction. So a rollback-only marker set in the inner transaction scope does affect the outer transaction's chance to actually commit (as you would expect it to).

 

However, in the case where an inner transaction scope sets the rollback-only marker, the outer transaction has not decided on the rollback itself, and so the rollback (silently triggered by the inner transaction scope) is unexpected. A corresponding UnexpectedRollbackException is thrown at that point. This is expected behavior so that the caller of a transaction can never be misled to assume that a commit was performed when it really was not. So if an inner transaction (of which the outer caller is not aware) silently marks a transaction as rollback-only, the outer caller still calls commit. The outer caller needs to receive an UnexpectedRollbackException to indicate clearly that a rollback was performed instead.

 

当事务传播性设置为PROPAGATION_REQUIRED的时候,Spring将为每一个应用了这个设置的方法创建一个逻辑上的事务(相对于物理事务而言)。每一个这样的逻辑事务都能够单独地决定rollback-only状态(即决定该事务是否回滚),这是与逻辑上独立于内部事务的外部事务一起的(这里的逻辑上独立是指内部事务和外部事务都拥有自己的逻辑事务属性)。当然,对于标准的PROPAGATION_REQUIRED行为,所有这些事务(无论是内部事务还是外部事务)都会对应为同一个物理事务。如果内部事务里面设置了rollback-only标志的话将会影响到外部事务的提交(这其实也是你期望的行为)。

 

这段话其实就是说如果一个外部事务和它的内部事务设置的属性都是PROPAGATION_REQWUIRED的话,那么这些事务实际上都处在同一个物理事务中,每一个事务都能够单独地决定该物理事务是否回滚,只需要将该自己设置为rollback-only。

 

 

然而,有这样的一种情况,当一个内部事务设置了rollback-only标识(这样的话整个物理事务就需要回滚了),而外部事务却决定不回滚(如果这个内部事务抛出异常的话外部事务可以通过在代码中捕获这个异常来防止因抛出异常而回滚,但是外部事务却不能干涉内部事务将其自己设置为rollback-only),这样的话,这个回滚就不是外部事务所期望的了。在这个节骨眼上将会抛出一个一个相应的UnexpectedRollbackException。这是符合预期的行为,因为这样的话事务的调用者就不会误认为这个事务是已提交的(因为某个内部事务已经标识为rollback-only了,所以外部事务不应该提交的)。因此如果一个内部事务(外部调用者并不知道)默默地标识为rollback-only,外部调用者仍旧称为commit。外部调用者需要接收到一个

UnexpectedRollbackException来明明白白地知道发生了一个回滚而不是commit。

 

这段话其实就是说如果某个内部事务将其自己标识为rollback-only了,那么整个物理事务就需要回滚,如果外部事务尝试去提交整个物理事务,那么就会抛出UnexpectedRollbackException,只有这样外部事务的调用者才会知道某个内部事务要求回滚,不应该提交整个物理事务。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值