Spring中事务传播机制

2024-08-25 16:20
文章标签 java spring 机制 事务 传播

本文主要是介绍Spring中事务传播机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Spring事务传播机制是指在一个事务方法调用另一个事务方法时,Spring如何管理这些方法之间的事务边界。Spring在TransactionDefinition接口中定义了七种事务传播行为,以满足不同的业务需求。以下是对这七种传播机制的详细解释及举例说明:

1. REQUIRED(默认)

  • 描述:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  • 适用场景:大多数情况下使用此传播行为,确保多个事务操作在同一个事务中执行,以保持数据一致性。
  • 举例
    • 假设有methodAmethodB,其中methodB被标记为@Transactional
    • 如果methodA没有事务,调用methodB时,methodB会创建一个新的事务。methodA抛出异常不会影响methodB(methodB和methodA都不会回滚);methodB抛出异常methodB会混滚,methodA不会回滚。
    • 如果methodA也被标记为@Transactional(methodA可以是任意传播机制),则methodB会加入methodA的事务中。methodA发生异常methodA和methodB都会回滚;methodB发生异常也是methodB和methodA都会回滚。

@Service  
public class TransacationTest {  @Resource  private TransacationTest2 transacationTest2;  @Transactional  public void methodA() {  // methodA 中的其他操作(如果有的话)  transacationTest2.methodB();  // methodA 中的其他操作(如果有的话)  }  
}  @Service  
public class TransacationTest2 {  @Transactional  public void methodB() {  // 代码块,可能会抛出异常  }  
}

 当 methodA 的事务被标记为需要回滚时,Spring 会在事务的边界(即事务性代理的拦截器)处执行回滚操作。这意味着 methodA 中的所有数据库操作(包括 methodB 中的操作)都会被回滚。

@Service  
public class TransacationTest {  @Resource  private TransacationTest2 transacationTest2;  public void methodA() {  // methodA 中的其他操作(如果有的话)  transacationTest2.methodB();  // methodA 中的其他操作(如果有的话)  }  
}  @Service  
public class TransacationTest2 {  @Transactional  public void methodB() {  // 代码块,可能会抛出异常  }  
}

如果 methodB 发生了异常,methodB 中的操作会回滚,但 methodA 方法中的其他操作(在 methodB 调用之前和之后的部分)不会受到影响,因为它们并不在 methodB 的事务性上下文中。如果 methodA 中的其他操作也需要事务支持,并且你希望它们能够参与到同一个事务中,那么你应该在 methodA 上也使用 @Transactional 注解。

@Service  
public class TransacationTest {  @Resource  private TransacationTest2 transacationTest2;  @Transactional  public void methodA() {  // methodA 中的其他操作(如果有的话)  transacationTest2.methodB();  // methodA 中的其他操作(如果有的话)  }  
}  @Service  
public class TransacationTest2 {  public void methodB() {  // 代码块,可能会抛出异常  }  
}

如果 methodB 中抛出了运行时异常,并且这个异常没有被捕获并处理,那么 methodA 和 methodB 中的所有操作都会因为事务的回滚而被撤销。这是因为 methodB 的执行是在 methodA 的事务性上下文中进行的。

2. SUPPORTS

  • 描述:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。
  • 适用场景:适用于既能在事务内执行,也能在事务外执行的操作,如某些只读操作或性能要求不高的操作。
  • 举例
    • 假设有methodAmethodB,其中methodB被标记为@Transactional(propagation = Propagation.SUPPORTS
    • 如果methodA没有事务,调用methodB时,methodB以非事务的方式运行methodA抛出异常不会影响methodB(methodB和methodA都不会回滚);methodB抛出异常methodB和methodA不会回滚。
    • 如果methodA也被标记为@Transactional(methodA可以是任意传播机制),则methodB会加入methodA的事务中。methodA发生异常methodA和methodB都会回滚;methodB发生异常也是methodB和methodA都会回滚。

3. MANDATORY

  • 描述:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
  • 适用场景:适用于必须在现有事务中执行的操作,通常用于一些关键业务逻辑,要求调用者必须在事务中运行。
  • 举例
    • 如果methodA没有事务,调用被标记为MANDATORYmethodB时,会抛出异常。

4. REQUIRES_NEW

  • 描述:总是启动一个新的事务。如果当前存在事务,则将当前事务挂起。
  • 适用场景:适用于需要独立事务的情况,例如记录日志或审计信息,不希望这些操作受到主事务的影响。
  • 举例
    • 无论methodA是否有事务,methodB(被标记为REQUIRES_NEW)都会启动一个新的事务。
    • 假设有methodAmethodB,其中methodB被标记为@Transactional(propagation = Propagation.REQUIRES_NEW
    • 如果methodA没有事务,调用methodB时,methodB会启动一个新事务运行methodA抛出异常不会影响methodB(methodB和methodA都不会回滚);methodB抛出异常methodB会回滚,methodA不会回滚。
    • 如果methodA也被标记为@Transactional(methodA可以是任意传播机制),则methodB会开启一个独立的事务。methodA发生异常methodA会回滚,methodB不会回滚,因为使用的不是同一个事务,不会相互影响;methodB发生异常methodB和methodA都会回滚,虽然不是同一个事务,但是methodB是methodA调用的,抛出的异常实际上是抛出给了methodA,所以两者都会回滚。

5. NOT_SUPPORTED

  • 描述:以非事务方式执行操作。如果当前存在事务,则将当前事务挂起。
  • 适用场景:适用于不需要事务支持的操作,或某些性能要求高、不希望受到事务管理开销影响的操作。
  • 举例
    • 如果methodA有事务,调用被标记为NOT_SUPPORTEDmethodB时,methodB的执行将不会在事务中。

6. NEVER

  • 描述:以非事务方式执行,如果当前存在事务,则抛出异常。
  • 适用场景:适用于明确不希望在事务中执行的操作,如某些数据库操作可能不支持事务。
  • 举例
    • 如果methodA有事务,调用被标记为NEVERmethodB时,会抛出异常。

7. NESTED

  • 描述:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则创建一个新的事务。嵌套事务依赖于底层数据库对保存点(savepoint)的支持。
  • 适用场景:适用于需要部分提交或回滚的复杂业务操作,如复杂的财务操作,某些步骤失败后需要回滚到特定点。
  • 举例
    • 类似于REQUIRED,但在复杂事务处理中,允许对事务进行更细粒度的控制。
  • 行为描述:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该传播行为等同于REQUIRED,即创建一个新的事务。嵌套事务是外部事务的一个子事务,它依赖于外部事务的存在。外部事务提交或回滚时,嵌套事务也会相应地提交或回滚,但如果嵌套事务失败并回滚,外部事务仍然可以提交。
  • 使用场景:适用于需要在某个方法内部进行独立的、可能回滚的操作,但又不希望这个回滚影响到外部事务的提交。

这篇关于Spring中事务传播机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1106048

相关文章

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

Java操作Word文档的全面指南

《Java操作Word文档的全面指南》在Java开发中,操作Word文档是常见的业务需求,广泛应用于合同生成、报表输出、通知发布、法律文书生成、病历模板填写等场景,本文将全面介绍Java操作Word文... 目录简介段落页头与页脚页码表格图片批注文本框目录图表简介Word编程最重要的类是org.apach

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP

SpringBoot+Docker+Graylog 如何让错误自动报警

《SpringBoot+Docker+Graylog如何让错误自动报警》SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK... 目录01 Spring Boot 默认日志框架解析02 Spring Boot 日志级别详解03 Sp

java中反射Reflection的4个作用详解

《java中反射Reflection的4个作用详解》反射Reflection是Java等编程语言中的一个重要特性,它允许程序在运行时进行自我检查和对内部成员(如字段、方法、类等)的操作,本文将详细介绍... 目录作用1、在运行时判断任意一个对象所属的类作用2、在运行时构造任意一个类的对象作用3、在运行时判断

java如何解压zip压缩包

《java如何解压zip压缩包》:本文主要介绍java如何解压zip压缩包问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java解压zip压缩包实例代码结果如下总结java解压zip压缩包坐在旁边的小伙伴问我怎么用 java 将服务器上的压缩文件解压出来,

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具

Spring WebFlux 与 WebClient 使用指南及最佳实践

《SpringWebFlux与WebClient使用指南及最佳实践》WebClient是SpringWebFlux模块提供的非阻塞、响应式HTTP客户端,基于ProjectReactor实现,... 目录Spring WebFlux 与 WebClient 使用指南1. WebClient 概述2. 核心依

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

Spring IoC 容器的使用详解(最新整理)

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean... 目录1. 应用分层2. IoC 的介绍3. IoC 容器的使用3.1. bean 的存储3.2. 方法注