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中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows