首页 > 其他分享 >Spring 七种事务传播性介绍

Spring 七种事务传播性介绍

时间:2024-01-04 11:04:46浏览次数:37  
标签:事务 七种 Spring 回滚 传播 开启 执行 方法

作者:vivo 互联网服务器团队 - Zhou Shaobin

本文主要介绍了Spring事务传播性的相关知识。

Spring中定义了7种事务传播性:

  • PROPAGATION_REQUIRED
  • PROPAGATION_SUPPORTS
  • PROPAGATION_MANDATORY
  • PROPAGATION_REQUIRES_NEW
  • PROPAGATION_NOT_SUPPORTED
  • PROPAGATION_NEVER
  • PROPAGATION_NESTED

在Spring环境中,含有事务的方法嵌套调用,事务是如何传递的规则,以及每种规则是如何开展工作的。文章还提到每种事务传播性是如何使用的,方便读者依据实际的场景,使用不同的事务规则。

一、什么是Spring事务的传播性

Spring 事务传播性是指, 在Spring的环境中,当多个含有事务的方法嵌套调用时,每个事务方法都处于自己事务的上下文中,其提交或者回滚行为应该如何处理。

通俗讲,就是当一个事务方法调用另外一个事务方法时,事务如何跨上下文传播。

Spring 七种事务传播性介绍_事务的传播

1)当事务方法A调用事务方法B时,事务方法B是合并到事务方法A中,还是开启新事务?

2)当事务方法B抛出异常时  ,在合并事务或者开启新的事务的场景中,事务的回滚是如何处理的 ?

以上事务的处理规则,都取决于事务传播级别的设置。

二、事务的传播性都有哪些行为

Spring 七种事务传播性介绍_事务的提交和回滚_02

事务的传播行为,主要分为三种类型,分别是:支持当前事务不支持当前事务嵌套事务

2.1 支持当前事务

REQUIRED:默认的事务传播级别,表示如果当前方法已在事务内,该方法就在当前事务中执行,否则,开启一个新的事务并在其上下文中执行。

SUPPORTED:当前方法在事务内,则在其上下文中执行该方法,否则,开启一个新的事务。

MANDATORY:必须在事务中执行,否则,将抛出异常。

2.2 不支持当前事务

REQUIRES_NEW:无论当前是否有事务上下文,都会开启一个事务  。如果已经有一个事务在执行 ,则正在执行的事务将被挂起 ,新开启的事务会被执行。

事务之间相互独立,互不干扰。

NOT_SUPPORTED:不支持事务,如果当前存在事务上下文,则挂起当前事务,然后以非事务的方式执行。

NEVER:不能在事务中执行,如果当前存在事务上下文,则抛出异常。

2.3 嵌套事务

NESTED:嵌套事务,如果当前已存在一个事务的上下文中,则在嵌套事务中执行,如果抛异常,则回滚嵌套事务,而不影响其他事务的操作。

三、每种事务的传播性如何工作

3.1 REQUIRED

默认的事务传播行为,保证多个嵌套的事务方法在同一个事务内执行,并且同时提交,或者出现异常时,同时回滚。

这个机制可以满足大多数业务场景。

Spring 七种事务传播性介绍_Spring_03

例子 :

Spring 七种事务传播性介绍_Spring_04

Spring 七种事务传播性介绍_事务的提交和回滚_05

1)类TestAService的方法通过声明式事务的方式,加上了事务注解@Transactional ,并设置事务的传播性为REQUIRED。

2)调用者调用TestAService的A方法时,如果调用者没有开启事务,那么A方法会开启一个事务。

A方法的具体执行过程如下 :

a. 执行insert,但没有提交;

b. 调用TestBServcie的B方法,由于B方法也声明了事务,并且传播性是REQUIRED,所以方法B的事务,合并到方法A开启的事务中。

c. 方法B执行insert操作,此时也没有提交。

3)由于这两个方法的操作都在同一个事务中执行,当这两个方法所有操作执行成功之后,提交事务。

嵌套调用链路:

Spring 七种事务传播性介绍_Spring_06

当方法B 执行时抛出了 Exception 异常后,事务是如何处理的 ?

1)方法B声明了事务,insert操作会回滚

2)由于方法A和方法B 同属一个事务,方法A也会执行回滚,由此说明该规则保证了事务的原子性。

嵌套调用,异常后的链路:

Spring 七种事务传播性介绍_事务的提交和回滚_07

如果 方法B 抛出异常后,方法A 使用 try-catch 处理了方法B的异常(如下代码),并没有向外抛出,此时事务又如何处理的 ?

Spring 七种事务传播性介绍_事务的提交和回滚_08

方法A也会回滚。

从事务的特性我们可知,事务具有原子性。方法A和方法B同属一个事务,当方法B抛出异常,触发回滚操作后,整个事务的操作都会回滚。

因此,Spring 在处理事务过程中,当事务的传播性设置为REQUIRED,在整个事务的调用链上,任何一个环节抛出的异常都会导致全局回滚。

3.2 REQUIRES_ NEW

每次都开启一 个新的事务。

Spring 七种事务传播性介绍_事务的提交和回滚_09

例子:

Spring 七种事务传播性介绍_事务的提交和回滚_10

上面例子中,方法B的传播性设置为 REQUIRES_NEW,方法A仍然是REQUIRED,当A调用B时,具体调用链路如下:

Spring 七种事务传播性介绍_事务的传播_11

具体执行过程:

  • 方法A被执行前,如果调用者没有开启事务,方法A开启一个事务1,然后执行insert ,此时没有提交;
  • 方法B的事务传播性设置为REQUIRES_NEW,当被方法A调用时,此时方法A的事务1会被挂起,方法B开启自己的事务2,然后执行insert,此时并没有提交;
  • 当方法B执行完毕后,提交事务2;
  • 恢复事务1,最终提交。

当 方法B 执行时抛出了异常,会发生什么?

方法B的insert操作会被回滚掉,方法A不受影响。但这里有个前提,方法A需要try-catch方法B的异常,使其异常不会往上传递,从而导致方法A接收到异常,导致回滚。

Spring 七种事务传播性介绍_Spring_12

3.3  SUPPORTED

当外层方法A存在事务,方法B加入到当前事务中,以事务的方式执行。

Spring 七种事务传播性介绍_事务的提交和回滚_13

当外层方法A不存在事务,方法B不会创建新的事务,以非事务的方式执行。

Spring 七种事务传播性介绍_事务的提交和回滚_14

例子1:

Spring 七种事务传播性介绍_事务的传播_15

Spring 七种事务传播性介绍_Spring_16

以上例子,方法A没有加事务注解,方法B的加了事务注解,并且传播为SUPPORTS。

具体执行过程:

  • 方法A以非事务的方式执行insert操作。
  • 方法B被调用,由于其外层事务A没有开启事务,方法B也是以非事务方法执行insert操作。

Spring 七种事务传播性介绍_Spring_17

例子2:

Spring 七种事务传播性介绍_事务的传播_18

以上例子,方法A和B都加上了事务注解,其中方法A的传播性为REQUIRED,方法B的传播性为SUPPORTS。

具体执行过程:

  • 如果方法A的调用方没有开启事务,则方法A开启事务,并执行insert操作,但没有提交;
  • 方法B被调用,由于其外层方法A开启了事务,因此方法B加入到方法A开启的事务中,并执行insert,但没有提交;
  • 当事务中的所有操作执行成功后,事务提交。

Spring 七种事务传播性介绍_事务的提交和回滚_19

3.4  NOT_SUPPORTED

不支持事务。

如果外层方法存在事务,则挂起外层事务,以非事务方式执行,执行完毕后,恢复外层事务。

Spring 七种事务传播性介绍_事务的传播_20

例子:

Spring 七种事务传播性介绍_事务的传播_21

以上例子:方法A和B都加上了事务注解,方法A的传播性为REQUIRED,方法B为NOT_SUPPORTED。

具体执行过程:

  • 如A的调用方没有开启事务,方法A开启事务,并执行insert,但没有提交。
  • 方法A调用方法B时,方法B的传播性为NOT_SUPPORTED,不支持事务,然后挂起外层方法A的事务,方法B以非事务的方式执行insert。
  • 方法B执行完毕后,恢复方法A的事务,最终提交事务。

调用链路过程:

Spring 七种事务传播性介绍_事务的传播_22

3.5 NEVER

不支持事务

当外层方法A开启了事务,方法B抛出异常

Spring 七种事务传播性介绍_事务的提交和回滚_23

例子:

Spring 七种事务传播性介绍_事务的提交和回滚_24

以上代码,两个方法都打上了事务注解,方法A的传播性是REQUIRED,方法B的传播性是NEVER。

具体执行过程:

  • 方法A开启事务,执行insert,没有提交。
  • 含有事务的方法A调用方法B,方法B的传播性是NEVER,表示不支持事务,因此方法B抛出异常。
  • 方法A的事务执行回滚。

Spring 七种事务传播性介绍_事务的提交和回滚_25

3.6 MANDATORY

必须在事务中执行。

如果外层方法A没有开启事务,方法B抛出异常。

Spring 七种事务传播性介绍_Spring_26

如果外层方法A开启了事务,方法B加入事务,方法A&B在同一事务中执行。

Spring 七种事务传播性介绍_事务的传播_27

例子:

Spring 七种事务传播性介绍_事务的提交和回滚_28

以上例子,方法A没有加事务注解,方法B 的传播性为 MANDATORY。

具体执行过程:

  • 方法A的调用方如果本身没有开启事务,方法A执行前不会开启事务。
  • 当非事务方法A调用方法B时,由于方法B的传播性为MANDATORY,必须在事务中执行,条件不满足,抛出异常。

Spring 七种事务传播性介绍_事务的提交和回滚_29

3.7 NESTED

嵌套事务

  • 如果外层方法A不存在事务,内层方法B的规则与REQUIRED 一致。
  • 如果外层方法A存在事务,内层方法B做为外层方法A事务的子事务执行,两个方法是一起提交,但子事务是独立回滚。
    内层方法B抛出异常,则会回滚方法B的所有操作,但不影响外层事务方法A。(方法A需要try-catch子事务,避免异常传递到父层事务)
    外层方法A回滚,则内层方法B也会回滚。
  • 该传播性的特点是可以保存状态点,当回滚时,只会回滚到某一个状态点,保证了子事务之间的独立性,避免嵌套事务的全局回滚。

Spring 七种事务传播性介绍_Spring_30

例子:

Spring 七种事务传播性介绍_事务的提交和回滚_31

以上例子,方法A的传播性为REQUIRED,方法B为NESTED。

具体执行过程:

  • 方法A执行时,如调用方没有开启事务,则开启一个事务。
  • 方法B被外层方法A调用时,因为方法B的传播性为NESTED,方法B在此处建立savepoint,标记insert行为。
  • 当方法B抛出异常,其insert操作会回滚,但只会回滚到savepoint,(前提是方法A要try-catch方法B,使方法B的异常不会往外传递)。
  • 方法B回滚后,方法A的事务提交。

调用链路:

Spring 七种事务传播性介绍_Spring_32

四、总结

本文解释了Spring框架中的事务传播性,即多个业务方法之间调用时事务如何处理的规则。Spring提供了七种传播级别,如PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW等。

每种级别都有适用场景和限制,本文提供了一些示例,介绍了声明式事务如何使用,每种事务的规则,产生哪种行为,当方法抛出异常时,事务的提交和回滚是如何被处理的。正确处理事务对于任何企业级应用程序都是必要的,了解Spring事务传播性是构建高效、可靠和可扩展应用程序的关键。

标签:事务,七种,Spring,回滚,传播,开启,执行,方法
From: https://blog.51cto.com/u_14291117/9097017

相关文章

  • SpringBoot+modbus4j实现ModebusTCP通讯读取数据
    场景Windows上ModbusTCP模拟Master与Slave工具的使用:Windows上ModbusTCP模拟Master与Slave工具的使用ModebusTCPModbus由MODICON公司于1979年开发,是一种工业现场总线协议标准。1996年施耐德公司推出基于以太网TCP/IP的Modbus协议:ModbusTCP。Modbus协议是一项应用层报文传输协议,包......
  • SpringBoot中读取yml中配置的list对象的配置项
    场景SpringBoot中通过ConfigurationProperties注解的方式读取application.yml中配置的属性值:SpringBoot中通过ConfigurationProperties注解的方式读取application.yml中配置的属性值_demoenabled:true参考上面获取yml配置文件中简单的配置项的方式。如果需要获取application.yml中......
  • 记录Springboot项目部署到服务器
    搞了一个月,开发了一个缩减版的管理系统,主要功能:对于进入海康门禁的老师,需要填报使用记录。用Springboot开发真的是便捷,专注于业务开发,不关心底层和架构。第一步:搭建配置服务器服务器:虚拟机Windows2016Server 64bit,内存32G,磁盘400GMysql:8.0.34Springboot:3.0.11IDEA:2023.1Ja......
  • 【微服务】springboot整合kafka-stream使用详解
    目录一、前言二、kafkastream概述2.1什么是kafkastream2.2为什么需要kafkastream2.2.1对接成本低2.2.2节省资源2.2.3使用简单2.3kafkastream特点2.4kafkastream中的一些概念2.5 KafkaStream应用场景三、环境准备3.1搭建zk3.1.1自定义docker网络3.1.2 拉取zk镜像3.......
  • Spring MVC 源码分析 - WebApplicationContext 容器的初始化
    随着 SpringBoot 和 SpringCloud 在许多中大型企业中被普及,可能你已经忘记当年经典的Servlet+SpringMVC的组合,是否还记得那个 web.xml 配置文件。在开始本文之前,请先抛开 SpringBoot 到一旁,回到从前,一起来看看Servlet是怎么和SpringMVC集成,怎么来初始化Sprin......
  • Spring Boot 自动配置功能介绍
    SpringBoot自动配置功能介绍SpringBoot是一个流行的Java开发框架,它提供了许多便利的功能和工具,帮助开发者快速构建应用程序。其中一个最引人注目的特性是其强大的自动配置功能。什么是自动配置?在传统的Java开发中,我们通常需要手动配置应用程序的各个组件和依赖项。这可......
  • 【JDK新特性】JDK和Springboot各版本新特性介绍
    目录参考资料以下是一些较新版本的JDK的主要新特性介绍:JDK8:Lambda表达式:引入了函数式编程的概念,使得代码更简洁、可读性更强。StreamAPI:提供了一种高效处理集合数据的方式,支持并行处理。默认方法(DefaultMethods):接口可以包含具有默认实现的方法。方法引用(MethodReferences):通过......
  • Spring Boot 正式弃用 Java 8。。
    大家好,我是R哥。关注Spring框架的都知道,因为Spring6.0要求最低JDK17+,所以SpringBoot3.0也必须JDK17+了,但是3.0出来的时候,一站式生成项目还是可以选Java8的,如下图所示:这是Spring提供的一站式生成Spring应用的网站,这个网站可以帮助开发人员一键生成符合Sprin......
  • 超级详细的数据库中的事务机制学习笔记
    事务的英文是transaction,从英文中你也能看出来它是进行一次处理的基本单元,要么完全执行,要么都不执行。事务的特性:ACIDA,也就是原子性(Atomicity)。组成物质的基本单位,也是我们进行数据处理操作的基本单位。C,就是一致性(Consistency)。一致性指的就是数据库在进行事务操作后,会由原来的一......
  • Spring最全的依赖注入方式
    Spring 框架中最核心思想就是:IOC(控制反转):即转移创建对象的控制权,将创建对象的控制权从开发者转移到了 Spring 框架的IoC容器。AOP(切面编程):将公共行为(如记录日志,权限校验等)封装到可重用的模块中,而使原本的模块内只需关注自身的个性化行为。本文将主要介绍 Spring 中 I......