首页 > 其他分享 >Spring事务传播机制

Spring事务传播机制

时间:2022-12-09 14:00:37浏览次数:30  
标签:事务 insertRoleMenu Spring 开启 传播 回滚 方法


Spring事务传播机制

  • ​​Spring事务传播类型​​
  • ​​REQUIRED​​
  • ​​SUPPORTS​​
  • ​​MANDATORY​​
  • ​​REQUIRES_NEW​​
  • ​​NOT_SUPPORTED​​
  • ​​NEVER​​
  • ​​NESTED​​
  • ​​总结​​
  • ​​Spring事务举例​​
  • ​​无事务情况​​
  • ​​父方法未开启事务,子方法开启事务​​
  • ​​父方法开启事务,子方法未开启事务​​
  • ​​父方法开启事务,子方法开启事务​​
  • ​​父方法开启REQUIRED事务,子方法开启NOT_SUPPORTED事务​​
  • ​​父方法开启REQUIRED事务,子方法开启REQUIRES_NEW事务​​
  • ​​父方法开启REQUIRED事务,子方法开启REQUIRES_NEW事务​​
  • ​​父方法开启REQUIRED事务,子方法开启REQUIRES_NEW事务​​
  • ​​Spring 事务失效场景​​
  • ​​数据库不支持事务​​
  • ​​事务方法未被Spring管理​​
  • ​​事务方法私有private​​
  • ​​同一个类中的方法调用​​
  • ​​不正确的异常捕获​​
  • ​​错误的异常类型​​
  • ​​总结​​

Spring事务传播类型

本文主要是讲述Spring事务传播机制,也就是大家开发过程中多多少少会遇到的父方法调用子方法,或者A方法调用B方法时事务的传播机制问题,但是在开始讲Spring事务传播机制之前需要先讲一下Spring事务的几种传播类型,如图

Spring事务传播机制_回滚

REQUIRED

REQUIRED表示如果当前没有事务,就创建一个事务,如果已经存在一个事务,就加入该事务,是Spring默认的事务传播类型

Spring事务传播机制_后端_02


也就是说如果外部不存在事务,就开启新的事务,如果外部存在事务,就加入该事务中,如果调用者发生异常,那么调用者和被调用者的事务都回滚。

SUPPORTS

SUPPORTS表示支持当前事务,如果当前没有事务,就以非事务的方式执行,也就是说外部不存在事务,不会开启新事务,外部存在事务时就加入该事务。

MANDATORY

MANDATORY表示支持当前事务,但是跟SUPPORTS不同的是这种事务传播类型具备强制性,当前操作必须存在事务,如果不存在,则抛出异常。

REQUIRES_NEW

REQUIRES_NEW表示如果当前存在事务,则把当前事务挂起,重新创建新的事务并执行,知道新的事务提交或回滚,才会恢复执行原来的事务。这种事务传播类型新创建的事务和被挂起的事务没有任何关系,他们是两个相互独立的事务,外部事务失败后回滚,不会回滚内部事务的执行结果,内部事务执行失败抛出异常,被外部事务捕获时,外部事务可以不处理内部事务的回滚操作。

NOT_SUPPORTED

NOT_SUPPORTED表示以非事务方式执行,如果当前操作在一个事务中,就把当前事务挂起,以非事务方式运行,直到操作完成再恢复事务执行。

NEVER

NEVER表示以非事务的方式执行,如果当前操作存在事务,则抛出异常。

NESTED

NESTED表示如果当前方法有一个事务正在运行,则这个方法应该运行在一个嵌套事务中,被嵌套的事务可以独立于被封装的事务进行提交或回滚,也就是说如果封装事务存在,并且外层事务异常回滚,那么内层事务必须回滚,如果内层事务回滚,不影响外层事务的提交和回滚,当封装事务不存在时,按照REQUIRED事务传播类型执行。

总结

上面7种事务传播类型,日常用到的基本上就REQUIRED、REQUIRES_NEW、NOT_SUPPORTED这几种。

Spring事务举例

现在有这样一种场景,权限管理系统保存角色的时候同时保存角色绑定的菜单,下面开始测试,数据库角色表、角色绑定菜单表 初始数据情况 sys_role、sys_role_menu

Spring事务传播机制_回滚_03

无事务情况

父方法 insertRole 保存角色,子方法 insertRoleMenu 绑定角色菜单,代码如图

Spring事务传播机制_子方法_04


设置insertRoleMenu 内部发生异常,则insertRole 保存角色(普通角色)成功,insertRoleMenu 绑定角色菜单失败,验证结果

Spring事务传播机制_子方法_05

父方法未开启事务,子方法开启事务

父方法未开启事务,子方法开启默认事务传播类型REQUIRED,代码如图

Spring事务传播机制_回滚_06


设置insertRoleMenu 内部发生异常,同时insertRoleMenu 开启Spring默认事务,而insertRole未添加事务注解,则insertRole保存角色(普通角色1)成功,insertRoleMenu 绑定角色菜单内部发生异常,事务回滚,验证结果

Spring事务传播机制_回滚_07

父方法开启事务,子方法未开启事务

父方法开启默认事务传播类型,子方法未开启事务,代码如图

Spring事务传播机制_子方法_08


设置insertRoleMenu 内部发生异常,同时insertRole 开启Spring默认事务,而insertRoleMenu未添加事务注解,则insertRoleMenu 内部发生异常,会影响外部insertRole方法的执行,此时均发生回滚,验证结果

Spring事务传播机制_java_09


新增(普通角色2)异常回滚,绑定角色菜单异常回滚。

父方法开启事务,子方法开启事务

父方法开启Spring默认事务传播类型,子方法开启Spring默认事务传播类型

Spring事务传播机制_子方法_10


设置insertRoleMenu 内部发生异常,同时insertRole 开启Spring默认事务,insertRoleMenu开启Spring默认事务,则insertRoleMenu 内部发生异常,会影响外部insertRole方法的执行,此时均发生回滚,验证结果

Spring事务传播机制_后端_11


新增(普通角色3)异常回滚,绑定角色菜单异常回滚。

父方法开启REQUIRED事务,子方法开启NOT_SUPPORTED事务

父方法开启Spring默认事务传播类型,子方法开启NOT_SUPPORTED事务

Spring事务传播机制_子方法_12


设置insertRoleMenu 内部发生异常,同时insertRole 开启Spring默认事务,insertRoleMenu开启Spring NOT_SUPPORTED事务,由于insertRoleMenu将父方法事务挂起,且执行绑定角色菜单之后发生异常,则insertRoleMenu会执行成功,同时由于子方法发生异常,则会影响外部insertRole方法的执行,则insertRole执行失败,事务回滚,验证结果

Spring事务传播机制_回滚_13


新增(普通角色4)增加失败,绑定角色菜单执行成功。

父方法开启REQUIRED事务,子方法开启REQUIRES_NEW事务

父方法开启Spring默认事务传播类型,子方法开启Spring REQUIRES_NEW事务传播类型

Spring事务传播机制_后端_14


设置insertRoleMenu 内部发生异常,同时insertRole 开启Spring默认事务,insertRoleMenu开启Spring REQUIRES_NEW事务,此时insertRoleMenu发生异常时,则insertRoleMenu、insertRole均会执行失败,事务回滚,验证结果

Spring事务传播机制_子方法_15


新增(普通角色5)增加失败,绑定角色菜单执行失败,事务回滚。

父方法开启REQUIRED事务,子方法开启REQUIRES_NEW事务

父方法开启Spring默认事务传播类型,子方法开启Spring REQUIRES_NEW事务传播类型,与上一种不同的是,异常产生发生在父方法最后一行

Spring事务传播机制_spring_16


设置insertRole 内部发生异常,且异常发生在最后一行,同时insertRole 开启Spring默认事务,insertRoleMenu开启Spring REQUIRES_NEW事务,此时insertRole发生异常时,则insertRole均会执行失败,事务回滚,insertRoleMenu执行成功,验证结果

Spring事务传播机制_回滚_17


新增(普通角色6)增加失败,绑定角色菜单执行成功。

父方法开启REQUIRED事务,子方法开启REQUIRES_NEW事务

父方法开启Spring默认事务传播类型,子方法开启Spring REQUIRES_NEW事务传播类型,异常产生发生在父方法最后一行,同时父方法、子方法是在同一个类中的内部调用

Spring事务传播机制_子方法_18


设置insertRole 内部发生异常,且异常发生在最后一行,同时insertRole 开启Spring默认事务,insertRoleMenu开启Spring REQUIRES_NEW事务,此时insertRole发生异常时,则insertRole、insertRoleMenu执行失败,事务回滚,验证结果

Spring事务传播机制_java_19


新增(普通角色7)增加失败,绑定角色菜单执行失败。

Spring 事务失效场景

数据库不支持事务

Spring事务生效的前提是连接的数据库存储引擎支持事务,比如Mysql 的MyISAM存储引擎不支持事务,则Spring事务会失效。

事务方法未被Spring管理

如果事务所在的类没有被交给Spring 管理,或者说没有加载到Spring IOC容器中,则该类方法上的事务会失效,比如

Spring事务传播机制_spring_20


如果没有@Service注解,则该类下的方法上的事务会失效。

事务方法私有private

如果事务注解的方法为内部的私有private方法,则事务会失效。

同一个类中的方法调用

同一个类中的父方法调用子方法,都开启了事务,如图

Spring事务传播机制_java_21


子方法的事务会失效

不正确的异常捕获

如果发生异常的代码被try catch捕获,则Spring 管理器无法感知到异常,导致事务失效。

错误的异常类型

Spring 事务默认的捕获的异常是RuntimeException,如果代码中执行失败抛出了Exception异常,则事务会失效

总结

以上内容基于日常工作及学习,仅供参考,有兴趣的同学也可以买一本《深入理解分布式事务 原理与实战》,读之受益良多。
参考文章:https://developer.aliyun.com/article/980760 ,同时也欢迎大家去我的社区博文


标签:事务,insertRoleMenu,Spring,开启,传播,回滚,方法
From: https://blog.51cto.com/u_10917175/5925158

相关文章

  • 反向传播不香了?解读 Hinton 大佬的 Forward-Forward 算法
    OverridetheentrypointofanimageIntroducedinGitLabandGitLabRunner9.4.Readmoreaboutthe extendedconfigurationoptions.Beforeexplainingtheav......
  • Spring boot 工程,http打印日志太多
    1、resources下添加配置文件:logback.xml,简单配置如下<?xmlversion="1.0"encoding="UTF-8"?><configurationscan="true"scanPeriod="60seconds"debug="false"><appe......
  • springboot项目打包没有生成target文件及jar包
    在pom文件中声明了pompom:打出来可以作为其他项目的maven依赖,在工程A中添加工程B的pom,A就可以使用B中的类。用在父级工程或聚合工程中。用来做jar包的版本控制。既不会出......
  • springboot项目搭建,访问controller接口失败
    错误表现:Thisapplicationhasnoexplicitmappingfor/error,soyouareseeingthisasafallback.在启动类上的注解:@EnableAutoConfiguration解决:使用这个注解......
  • SpringBoot+RabbitMQ实现消息订阅发送
    RabbitMQ安装(docker)拉取rabbitmq镜像文件#未指定版本,拉取最新版本root#dockerpullrabbitmq启动镜像root#dockerrun-d--hostnamemy-rabbit--na......
  • Spring Cloud 概要(What,特性,版本)
    1.WhatisSpringCloud?出自官方:​​官网入口​​SpringCloud为开发人员提供了一些工具用来快速构建分布式系统中的一些常见模式和解决一些常见问题(例如配置管理、服务发......
  • 在web.xml文件中的配置(spring和springmvc)
    初始化spring容器:<!--初始化spring容器:--><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-context.xml</p......
  • Spring Cloud 与 Spring Boot 的兼容版本
    SpringCloud版本SpringBoot版本Hoxton2.2xGreenwich2.1xFinchley2.0xEdgware1.5xDalston1.5xCamden1.4x或1.5xBrixton1.3x或1.4xAngel1.2x......
  • Spring事务
    Spring支持两种方式事务管理编程式的事务管理通过TransactionTemplate手动管理事务(几乎没有人用)在实际应用中很少使用,原因是要修改原来的代码,加入事务管理代码(侵入性)使......
  • spring事务注解
    步骤:在需要管理事务的方法或者类上面添加@Transactional注解配置注解驱动事务管理(事务管理注解生效的作用)(需要配置对特定持久层框架使用的事务管理器)根据​​我spring的博......