Spring事务传播嵌套

本文详细探讨了Spring框架中事务传播级别的概念,特别是PROPAGATION_NESTED与PROPAGATION_REQUIRES_NEW的区别,以及如何通过合理设置事务传播级别进行性能优化。通过对比不同传播级别的特性,文章提供了一种有效的方法来管理和控制复杂业务场景下的事务行为。

Transactional(propagation)

REQUIRED(默认):如果没有事务,则开启一个新的事务。如果存在一个事务,则加入当前事务。

NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。

REQUIRESNEW:总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。

SUPPORTS:如果没有事务,则非事务的执行。如果存在一个事务,则加入当前事务。

NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常。

NESTED:如果没有活动事务, 则按PROPAGATION_REQUIRED 属性执行,如果一个活动的事务存在,则运行在一个嵌套的事务中。

PROPAGATION_NESTED 与PROPAGATION_REQUIRES_NEW的区别

PROPAGATION_REQUIRES_NEW每次开启一个新的事务,同时挂起前一个正在运行的事务,开启的新事务会独立提交/回滚。之后被挂起的前一个事务继续运行,在结束时提交或回滚。
由此看来,当使用PROPAGATION_REQUIRES_NEW时,服务层的内部其实是由多个独立的小事务组成的一个大的事务。每个小事务彼此独立,互不影响。一旦内层事务进行了提交,外层事务不能对其进行回滚。
PROPAGATION_NESTED并不开启新的事务,它使用save point来代替事务,它可以选择在自己的逻辑内回滚,但它不能在自己的逻辑内提交,而必须等到外层的逻辑提交时一并提交。
由此看来,当使用PROPAGATION_NESTED时,服务层的内部只有一个事务存在,内嵌的事务回滚不会引起外层的事务回滚(如同上面说的,它可以在自己的逻辑内回滚),但外层的事务回滚会引起内嵌的事务回滚(因为内嵌的事务必须等到外层事务提交时才一并提交)。需要JDBC 3.0以上驱动及1.4以上的JDK版本支持。

常用

PROPAGATION_XXX的设置和性能优化

一般来说,PROPAGATION_REQUIRED的传播级别就已经够了。对于长时间、可分段的任务,如果也采用一个大的事务一次性提交,则一旦失败代价太大了。最典型的例子就是:大批量的数据导入,你总不能因为一条数据错了而将其它插入全部回滚吧!

这时可以考虑划分为小段的PROPAGATION_REQUIRED事务进行,多次独立提交事务。

也考虑考虑设置为PROPAGATION_NESTED,因为JDBC 3.0提供了save point机制,可以在事务未提交的情况下保存事务中间的状态,一旦回滚不会回滚全部,而是只回滚到save point点(根据时间)。那么我们可以把大的事务划分成多个小的内嵌事务,每个内嵌事务执行成功后刷新save point,如果全部成功则一次性提交,如果中间失败了则回滚则上一个save point,同时继续下一个内嵌事务,不怕将前面尚未提交的其它事务操作全部回滚。

和PROPAGATION_REQUIRED相比,好处就是事务提交的次数少了,可以一次性写入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值