spring事务的传播
关于事务的传播,我们先确定一个场景:方法A调用方法B,方法A可能存在事务,也可能不存在事务,我们这里重点关注方法B上定义的事务传播行为,以及方法B中出现异常时,方法A应该如何处理事务的提交或回滚(如果存在)。
@Autowired private ServiceB serviceB;
public void methodA() {
// do anything
serviceB.mehtodB();
// do anything
}
@Transactional(propagation = Propagation.NESTED)
public void mehtodB() {
// do anything
}
事务的传播行为类型
1 .PROPAGATION_REQUIRED(默认实现)
方法B的执行需要有事务,如果方法A有事务,那么方法B加入方法A的事务,方法A或B的异常都会导致整个事务回滚。
2 .PROPAGATION_SUPPORTS
方法B的执行支持事务,如果方法A存在事务,那么方法B加入方法A的事务,否则方法B以无事务的方式执行。此情景下,A方法事务回滚也将导致方法B回滚,方法A无事务则不影响。
3 .PROPAGATION_MANDATORY
方法B强制必须在事务条件下执行,方法B加入方法A的事务执行,如果方法A无事务,则抛出异常。
4 .PROPAGATION_REQUIRES_NEW
方法B必须在新事务中执行,如果A存在事务,那么把方法A的事务挂起;此种情境下,方法A和方法B的回滚不会影响到对方。
5 .PROPAGATION_NOT_SUPPORIED
方法B必须在无事务条件下执行,如果方法A存在事务,那么需要将方法A的事务挂起。
6 .PROPAGATION_NEVER
方法B必须在不存在事务的条件下执行,如果方法A存在事务,则抛出异常。
7 .PROPAGATION_NESTED
这里我们需要了解下嵌套事务的提交
- 我们把嵌套事务视作一棵树,根节点事务叫做顶层的事务,其它事务是顶层事务的子事务;
- 任何嵌套的子事务的提交和回滚,都必须在它的父事务提交后进行;嵌套的子事务可以独立于当前事务进行单独地提交或回滚;
- 任何父事务的回滚都会导致它的所有子事务的回滚。
嵌套事务,如果方法A存在事务,那么方法B的创建一个方法A事务的嵌套事务(从数据库的层面看,也可视为子事务),如果方法A不存在事务,那么行为与PROPAGATION_REQUIRED相同。
此处,父事务的回滚行为会导致子事务回滚;而子事务的回滚和提交独立于父事务。
注意事项
-
非public 方法会导致事务失效
-
事务默认的异常类型是: RuntimeException
本文作者:bokerr
本文链接:https://www.cnblogs.com/bokers/p/16063237.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步