Spring 事务和事务传播机制

article/2025/9/21 0:46:03

文章目录

  • 1. Spring 事务的实现
    • 1.1 Spring 手动操作事务
    • 1.2 Spring 声明式事务
      • 1.2.1 @Transactional 作用范围
      • 1.2.2 @Transactional 参数说明
      • 1.2.3 异常被捕获, 不会事务回滚
        • ① 解决办法 --- 将异常重新抛出
        • ② 解决办法 --- 手动回滚事务
  • 2. Spring 事务的隔离级别
    • 2.1 Spring事务的隔离级别有 5 种
    • 2.2 Spring 中设置事务隔离级别
  • 3. Spring 事务的传播机制
    • 3.1 事务传播机制有哪些?
    • 3.2 代码演示
      • 3.2.1 支持当前事务
      • 3.2.2 不支持当前事务
      • 3.2.3 不支持当前事务, NEVER 抛异常
      • 3.2.4 嵌套事务
    • 3.3 嵌套事务和加入事务的区别
      • 3.3.1 嵌套事务
      • 3.3.2 加入事务
      • 3.3.3 总结

1. Spring 事务的实现

Spring 中事务的实现有两种方法:

  1. 手动操作事务
  2. 声明式自动提交事务

1.1 Spring 手动操作事务

Spring 手动操作事务, 一共三个重要步骤: ①开启事务,②提交事务,③回滚事务

@RestController
public class UserController2 {@Resourceprivate UserService userService;// JDBC 事务管理器@Resourceprivate DataSourceTransactionManager dataSourceTransactionManager;// 定义事务属性@Resourceprivate TransactionDefinition transactionDefinition;@RequestMapping("/save")public Object save(User user) {// 1. 开启事务TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);// 插入数据库int result = userService.save(user);// 2. 提交事务dataSourceTransactionManager.commit(transactionStatus);// 3. 回滚事务dataSourceTransactionManager.rollback(transactionStatus);return result;}
}

1.2 Spring 声明式事务

在方法上添加 @Transactional 注解就可以实现了
无需手动开启事务和提交事务, 进入方法时自动开启事务, 方法执行完会自动提交事务, 如果中途发生了没有处理的异常会自动回滚事务

@RestController
public class UserController2 {@Resourceprivate UserService userService;@RequestMapping("/save")@Transactionalpublic Object save(User user) {int result = userService.save(user);return result;}
}

1.2.1 @Transactional 作用范围

@Transactional 可以用来修饰方法或类:

  • 修饰方法的时候, 需要注意只能应用到 public 方法上, 否则不生效.
  • 修饰类时, 表明该注解对该类中所有的 public 方法都生效.

1.2.2 @Transactional 参数说明

参数作用
value当配置了多个事务管理器时, 可以使用该属性指定选择哪个事务管理器
transactionManager当配置了多个事务管理器时, 可以使用该属性指定选择哪个事务管理器.
propagation事务的传播行为. 默认为 Propagation.REQUIRED
isolation事务的隔离级别. 默认为 Isolation.DAEFAULT
timeout事务的超时事件. 默认值为-1, 如果超过该时间限制但事务还没有完成, 则自动回滚事务.
readOnly指定事务是否只读事务. 默认为 false. 为了忽略那些不需要事务的方法, 比如读取数据, 可以设置为 read-only 为 true
rollbackFor用于指定能够触发事务回滚的异常类型, 可以指定多个异常类型
rollbackForClassName用于指定能够触发事务回滚的异常类型, 可以指定多个异常类型
noRollbackFor抛出指定的异常类型, 不回滚事务, 也可以指定多个异常类型
noRollbackForClassName抛出指定的异常类型, 不回滚事务, 也可以指定多个异常类型

1.2.3 异常被捕获, 不会事务回滚

当前的代码:

    @RequestMapping("/save")@Transactionalpublic Object save(User user) {int result = userService.save(user);try {int a = 10/0;}catch (Exception e) {e.printStackTrace();}return result;}

当前数据库表中的内容:

在这里插入图片描述
运行之后表中的内容
在这里插入图片描述
在这里插入图片描述
此时发现, 出现异常的情况, 不会发生事务回滚

① 解决办法 — 将异常重新抛出

    @RequestMapping("/save")@Transactionalpublic Object save(User user) {int result = userService.save(user);try {int a = 10/0;}catch (Exception e) {e.printStackTrace();throw e;}return result;}

在这里插入图片描述
此时数据库中也不会有数据
在这里插入图片描述

② 解决办法 — 手动回滚事务

使用 TransctionAspectSupport.currentTransactionStatus() 可以得到当前事务
然后使用 setRollbackOnly 就可以实现回滚.

    @RequestMapping("/save")@Transactionalpublic Object save(User user) {int result = userService.save(user);try {int a = 10/0;}catch (Exception e) {e.printStackTrace();TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}return result;}

在这里插入图片描述
在这里插入图片描述

2. Spring 事务的隔离级别

2.1 Spring事务的隔离级别有 5 种

  1. Isolation.DEFAULT: 以连接的数据库的事务隔离级别为主
  2. Isolation.READ_UNCOMMITTED: 读未提交, 可以读取到未提交的事务, 存在脏读
  3. Isolation.READ_COMMITTED: 读已提交, 只能读取到已经提交的事务, 解决了脏读, 但存在不可重复读
  4. Isolation.REPEATABLE_READ: 可重复读, 解决了不可重复读, 但存在幻读
  5. Isolation.SERIALIZABLE: 串行化, 可以解决所有并发问题, 但性能低

2.2 Spring 中设置事务隔离级别

只需要通过 @Transactional 中的 isolation 属性进行设置即可
在这里插入图片描述

3. Spring 事务的传播机制

Spring 事务传播机制定义了多个包含了事务的方法, 相互调用时, 事务是如何在这些方法间进行传递的

事务隔离级别 保证多个并发事务执行的可控性
 
事务传播机制 保证一个事务在多个调用方法间的可控性

3.1 事务传播机制有哪些?

Spring 事务的传播机制包含以下 7 种 :

  1. Propagation.REQUIRED: 默认的事务传播级别, 它表示如果当前存在事务, 则加入该事务; 如果当前没有事务, 则创建一个新的事务.
  2. Propagation.SUPPORTS: 如果当前存在事务, 则加入该事务; 如果当前没有事务, 则以非事务的方式继续运行.
  3. Propagation.MANDATORY: 如果当前存在事务, 则加入该事务; 如果当前没有事务, 则抛出异常.
  4. Propagation.REQUIRES_NEW: 表示创建一个新的事务, 如果当前存在事务, 则把当前事务挂起.
  5. Propagation.NOT_SUPPORTED: 以非事务方式运行, 如果当前存在事务, 则把当前事务挂起.
  6. Propagation.NEVER: 以非事务方式运行, 如果当前存在事务, 则抛出异常.
  7. Propagation.NESTED: 如果当前存在事务, 则创建一个事务作为当前事务的嵌套事务来运行; 如果不存在事务, 则创建一个新的事务.

在这里插入图片描述

3.2 代码演示

3.2.1 支持当前事务

@RestController
public class UserController2 {@Resourceprivate UserService userService;@Resourceprivate LogService logService;@RequestMapping("/save")@Transactional(propagation = Propagation.REQUIRED)public Object save(User user) {int result = userService.save(user);logService.saveLog("用户插入: " + user.getUsername());return result;}
}

UserService 代码 和 LogService 代码
在这里插入图片描述

运行结果:

发现 LogSerivice 出错, 导致 LogService操作回滚, 也导致 UserService 报错

在这里插入图片描述
在这里插入图片描述

3.2.2 不支持当前事务

修改 UserServiceLogServicePropagation.REQUIRES_NEW

在这里插入图片描述

运行结果:

User表中插入成功, Log表中插入失败.

在这里插入图片描述
在这里插入图片描述

3.2.3 不支持当前事务, NEVER 抛异常

修改 LogServicePropagation=Propagation.NEVER
在这里插入图片描述
将 log的代码移到前面

    @RequestMapping("/save")@Transactionalpublic Object save(User user) {logService.saveLog("用户插入: " + user.getUsername());int result = userService.save(user);return result;}

运行结果:
执行到 logService.saveLog 这段就报错. 就不会继续往下走了.
在这里插入图片描述
在这里插入图片描述

3.2.4 嵌套事务

修改 LogServiceUserService 代码为 Propagation.NESTED
在这里插入图片描述
运行结果:

用户表和日志表都没有添加任何的数据

在这里插入图片描述
在这里插入图片描述

3.3 嵌套事务和加入事务的区别

3.3.1 嵌套事务

将嵌套事务中的 LogService 中进行当前事务的回滚操作.
在这里插入图片描述
运行结果:
User表操作成功, Log表操作失败.
在这里插入图片描述
在这里插入图片描述

3.3.2 加入事务

还是在 LogService 中 执行回滚操作.
在这里插入图片描述
运行结果:

此时 User表插入数据失败, Log表插入数据也失败.

在这里插入图片描述
在这里插入图片描述

3.3.3 总结

嵌套事务 (NESTED)加入事务 (REQUIRED) 的区别

  • 整个事务如果全部执行成功, 二者的结果是一样的.
  • 如果事务执行到一半失败了, 那么加入事务整个会全部回滚; 而嵌套事务会局部回滚, 不会影响上一个方法中执行的结果.

http://chatgpt.dhexx.cn/article/La9cL9dj.shtml

相关文章

关于Spring事务及其传播机制

目录 一丶Spring中事务的实现 <1>事务的四大特性有哪些<2>数据库并发一致性问题以及隔离级别的设置2>隔离可以解决的并发问题<3>Spring事务隔离级别 <1>事务的传播机制是什么&#xff1f;为什么需要传播机制<2>事务的传播机制有哪些&#x…

Spring事务传播机制--包含用例解释

Spring事务传播机制 一、何为Spring传播机制&#xff1a; Spring事务的传播机制就是&#xff0c;事务如何在方法的调用如何传播。 二、使用传播机制的时候的关键点&#xff1a; 使用声明式的事务时&#xff0c;调用方法和被调用方法不能在同一个类。比如同在一个service方法…

spring事务传播机制实例讲解

对于SQL事务的概念以及ACID性质&#xff0c;可以参见我的另一篇博文 http://kingj.iteye.com/admin/blogs/1675011spring的管理的事务可以分为如下2类&#xff1a; 逻辑事务 在spring中定义的事务通常指逻辑事务&#xff0c;提供比物理事务更抽象&#xff0c;方便的事务配置管…

Spring事务及事务传播机制

一.事务的含义:多个操作封装在一起&#xff0c;要么同时执行成功&#xff0c;一旦有一个操作执行失败&#xff0c;那么全部执行失败。这里给大家举个例子:比如A给B转账50元&#xff0c;而B没有收到这50元&#xff0c;此时A转账B这个操作也需要进行回滚&#xff0c;恢复到A给B没…

【 Spring 事务传播机制 】

文章目录 一、概念二、为什么需要事务传播机制&#xff1f;三、事务传播机制有哪些&#xff1f;四、Spring 事务传播机制使⽤和各种场景演示4.1 ⽀持当前事务&#xff08;REQUIRED&#xff09;4.2 不⽀持当前事务&#xff08;REQUIRES_NEW&#xff09;4.3 NESTED 嵌套事务4.4 嵌…

Spring事务与事务传播机制

目录 1.事务的基本概念 2.Spring事务的实现 3.事务隔离级别 4.事务传播机制 1.事务的基本概念 关于事务的一些基础概念我已经在MYSQL中讲解过了&#xff0c;有不了解的可以移步至此篇文章&#xff1a;MySQL基础——数据库索引与事务_invictusQAQ的博客-CSDN博客 2.Spring…

Spring事务、事务隔离级别、事务传播机制

Spring事务、事务隔离级别、事务传播机制 一、为什么需要事务&#xff1f;(回顾)二、Spring中事务的实现2.1 MySQL中的事务使用 (回顾)2.2 Spring编程式事务2.3 Spring 声明式事务2.3.1 Transactional 使用2.3.2 Transactional 作用范围2.3.3 Transactional 参数说明2.3.4 注意…

Spring 事务和事务的传播机制

1.Spring 中事务的实现方式 Spring 中的操作主要分为两类: 编程式事务 (了解) 声明式事务 编程式事务就是手写代码操作事务, 而声明式事务是利用注解来自动开启和提交事务. 并且编程式事务用几乎不怎么用. 这就好比汽车的手动挡和自动挡, 如果有足够的的钱, 大部分人应该都会选…

【Spring Boot】事务和事务传播机制

文章目录 1. 事务简单介绍2. Spring 中事务的实现2.1 Spring 手动操作事务2.2 Spring 声明式事务 3. Transactional 注解介绍3.1 Transactional 作用范围3.2 Transactional 参数说明3.3 Transactional 出现异常注意事项3.4 Transactional 工作原理 4. 事务隔离级别4.1 事务特性…

SpringBoot事务传播机制

Spring的事务传播机制:是指规定当程序中出现了多个方法出现了嵌套调用的时候&#xff0c;事务是如何进行传递的 支持当前事务:要有房子的 不支持当前事务:不许要有房子的 嵌套事务 1)定义:咱们之前所说的事务&#xff0c;都是针对一个方法的&#xff0c;咱们的Spring事务传播机…

Spring的事务传播机制(通俗易懂)

概述 Spring的事务传播机制有7种&#xff0c;在枚举Propagation中有定义。 1.REQUIRED PROPAGATION_REQUIRED&#xff1a;如果当前没有事务&#xff0c;就创建一个新事务&#xff0c;如果当前存在事务&#xff0c;就加入该事务&#xff0c;该设置是最常用的默认设置。 Tra…

Spring中的事务传播机制

目录 前言 1、Spring&#xff08;Spring Boot&#xff09;实现事务 1.1、通过代码的方式手动实现事务 1.2、通过注解Transactional的方式实现声明式事务 1.2.1、实现: 1.2.2、程序中有try-catch时&#xff0c;程序发生异常事务不会回滚 解决方案一&#xff1a;将异常抛出去 …

事务的7种传播机制和演示

文章目录 一、事务的传播机制1.1、nested 事务的几点说明&#xff1a; 二、示例2.1、前言&#xff1a;2.2、准备测试方法1&#xff09;创建beans.xml&#xff0c;开启事务2&#xff09;创建实体类和表&#xff08;表创建读者可自定义创建&#xff09;3&#xff09;创建service接…

事务传播行为

原文作者&#xff1a;https://blog.csdn.net/soonfly/article/details/70305683 事务传播行为 什么叫事务传播行为&#xff1f;听起来挺高端的&#xff0c;其实很简单。 即然是传播&#xff0c;那么至少有两个东西&#xff0c;才可以发生传播。单体不存在传播这个行为。 事务传…

[事务] 事务的传播机制

前言&#xff1a; Spring的事务&#xff0c;也就是数据库的事务操作&#xff0c;符合ACID标准&#xff0c;也具有标准的事务隔离级别。 但是Spring事务有自己的特点&#xff0c;也就是事务传播机制。 所谓事务传播机制&#xff0c;也就是在事务在多个方法的调用中是如何传递的&…

事物的传播机制

目录 1、事务的传播机制 2、测试 2.1、准备测试方法 2.2、事务传播机制的测试 2.2.1、REQUIRED 2.2.2、NOT_SUPPORTED 2.2.3、REQUIRES_NEW 2.2.4、MANDATORY 2.2.5、NEVER 2.2.6、SUPPORTS 2.2.7、NESTED 事务传播机制&#xff1a;就是事务在多个方法的调用中是如何…

Spring事务传播机制

目录 一、事务在Spring中是如何运作的 1.1 开启事务(DataSourceTransactionManager.doBegin) 二、Spring的事务传播机制 2.1 子事务的传播机制为REQUIRED 2.2 子事务的传播机制为REQUIRES_NEW 2.3 子事务的传播机制为NESTED 当我们在使用Spring所提供的事务功能时&#x…

Spring事务传播的7种机制

Spring 事务传播机制包含以下 7 种&#xff1a; 1. Propagation.REQUIRED&#xff1a;默认的事务传播级别&#xff0c;它表示如果当前存在事务&#xff0c;则加入该事务&#xff1b;如果 当前没有事务&#xff0c;则创建一个新的事务。 2. Propagation.SUPPORTS&#xff1a;如果…

事务的传播机制

目录 1.形象说明&#xff1a; 2.代码演示&#xff1a; 2.1 REQUIRED 2.1.1 验证共用一个事务 2.1.2 验证当前没有事务&#xff0c;就新建一个事务 2.2 SUPPORTS 2.2.1 支持使用当前事务 2.2.2 如果当前事务不存在&#xff0c;则不使用事务 2.3 MANDATORY 2.3.1 支持…

Spring事务传播机制详解

前言&#xff1a; Spring的事务&#xff0c;也就是数据库的事务操作&#xff0c;符合ACID标准&#xff0c;也具有标准的事务隔离级别。 但是Spring事务有自己的特点&#xff0c;也就是事务传播机制。 所谓事务传播机制&#xff0c;也就是在事务在多个方法的调用中是如何传递的&…