Spring 事务和事务传播机制

Spring 事务和事务传播机制

1. 事务的回顾

在 MySQL 学习阶段,已经了解到了事务是一组操作的集合,也就是把所有的操作作为一个整体,一起向数据库提交或者撤销操作,要么同时成功,要么同时失败

一个事务的操作流程包括了,开启事务,执行事务操作,提交事务或回滚事务,对于回滚事务来说,如果程序在执行过程中出现了错误,那么此时就需要执行回滚事务

2. 事务的实现方式

2.1. 编程式事务

Spring 手动操作事务和 MySQL 操作事务类似,也是分为开启事务,提交事务,回滚事务等三个操作,需要用到 DataSourceTransactionManager (事务管理器)来进行上述事务的操作,还需要用到 TransactionDefinition(事务的属性,获取事务时需要把这个类的对象传进去)

@RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @Autowired private DataSourceTransactionManager dataSourceTransactionManager; @Autowired private TransactionDefinition transactionDefinition; @RequestMapping("/registy") public String registy(String name, String password) { //开启事务,获取一个状态,之后回滚就回滚到了这个状态 TransactionStatus transaction = dataSourceTransactionManager.getTransaction(transactionDefinition); Integer reuslt = userService.insert(name, password); //提交事务(提交的是之前获取的状态) dataSourceTransactionManager.commit(transaction); return "注册成功"; } }

测试之后数据也是正常更新了

回滚的话调用的是 rollback 方法,再次进行插入数据,数据就没有更新,不过自增 id 还是变成了 3,对比提交事务的日志可以看出,这次没有提交事务的信息了

2.2. 声明式事务

上面的方式是比较麻烦的,需要自己写一大堆信息,来看声明式事务是如何操作的

首先需要添加依赖:

<dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> </dependency>

只需在要执行的方法上添加@Transactional注解,添加之后,如果没有发生异常就正常执行,如果发生了异常就回滚事务

来看异常的情况:

这时事务就没有提交,进行了回滚

3. @Transactional

@Transactional 可以用来修饰方法或类,修饰方法时,只有修饰 public 方法时才生效,修饰其他方法时不会报错,但也不生效,修饰类时,对该类中所有的 public 方法都生效

在目标方法执行开始之前会自动开启事务,执行结束之后会自动提交事务,如果方法执行过程中出现异常且异常未被捕获,就进行事务回滚操作

例如,把上面的异常代码 catch 起来,事务就正常提交了

但是如果捕获之后又进行抛出,那么事务还是会回滚的

还可以通过调用 setRollbackOnly 方法进行手动回滚

这样的话把异常捕获之后还可以回滚事务

3.1. rollbackFor

@Transactional默认只在遇到 RuntimeException 和 Error 时才进行回滚,非运行时异常就不会滚,来演示一下发生非运行异常时的情况:

虽然此时抛出了异常,但是事务还是提交了,并没有进行回滚,可以通过设置@Transactional注解的 rollbackFor 属性来指定那些异常要回滚

把 rollbackFor 设置为 Exception.class,表示 Exception 底下的子类异常都会发生回滚

@Transactional(rollbackFor = Exception.class) @RequestMapping("/r3") public String r3(String name, String password) throws IOException { Integer reuslt = userService.insert(name, password); if (true) { throw new IOException(); } return "注册成功"; }

此时再次测试,事务就回滚了

3.2. isolation

@Transactional 注解的 isolation 属性是可以设置事务的隔离级别的,参数类型是一个 Isolation 的枚举类,依次表示当前数据库默认使用的隔离级别和事务的四种隔离级别

可以根据需要进行设置

//设置事务的隔离级别 @Transactional(isolation = Isolation.DEFAULT) @RequestMapping("/r4") public String r4(String name, String password) throws IOException { Integer reuslt = userService.insert(name, password); if (true) { throw new IOException(); } return "注册成功"; }

4. 事务传播机制

事务传播机制是指在多个事务方法相互调用时,定义事务如何在这些方法之间传播的规则,也就是延用调用方法的事务还是再重新开启一个新事务

Spring 事务的传播机制有以下七种

事务传播机制

描述

理解(有 A,B 两个方法,A 调用 B 对于 B 来说)

  1. Propagation.REQUIRED

默认的事务传播级别。如果当前存在事务,则加入该事务。如果当前没有事务,则创建一个新的事务。

A 有事务就用 A 的,没有 B 就再开启新的

  1. Propagation.SUPPORTS

如果当前存在事务,则加入该事务。如果当前没有事务,则以非事务的方式继续运行。

A 没有事务就算了,B 就按照没有事务的方式执行

  1. Propagation.MANDATORY

如果当前存在事务,则加入该事务。如果当前没有事务,则抛出异常。

如果 A 没有事务,就抛出异常

  1. Propagation.REQUIRES_NEW

如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事务,Propagation.REQUIRES_NEW 修饰的内部方法都会新开启自己的事务,且开启的事务相互独立,互不干扰。

不管 A 有没有事务,B 都要开启新事务

  1. Propagation.NOT_SUPPORTED

以非事务方式运行,如果当前存在事务,则把当前事务挂起(不用)。

不管 A 有没有事务,B 都以非事务方式执行

  1. Propagation.NEVER

以非事务方式运行,如果当前存在事务,则抛出异常。

B 以非事务方式执行,如果 A 有事务就抛出异常

  1. Propagation.NESTED

如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行。如果当前没有事务,则该取值等价于 PROPAGATION_REQUIRED。

如果 A 有事务,B 就创建一个嵌套事务,如果没有就创建新的

4.1. REQUIRED

把 UserService 和 LogService 的两个方法都设置为 REQUIRED

@Slf4j @RestController @RequestMapping("/propaga") public class PropagationController { @Autowired private UserService userService; @Autowired private LogService logService; @Transactional @RequestMapping("/r1") public String registy(String name, String password) { userService.insert(name, password); logService.insertLog(name,"用户注册"); return "注册成功"; } }

在 PropagationController 中进行调用,此时 registy 就相当于 A ,调用的两个方法相当于 B,运行之后,如果其中一个方法发生异常,那么 registy 方法的整个事务都会回滚,也就是他们都用的是 A 的事务

4.2. REQUIRES_NEW

把 UserService 和 LogService 的两个方法都设置为 REQUIRES_NEW

此时就是无论 A 有没有事务, B 都新创建事务,所以当 B 的一个方法有异常时,是不会影响其他方法的

4.3. NEVER

如果设置为 NEVER 的话,A 调用 B,A 如果存在事务,就会报错

把 A 的事务取消掉就不会报错了

4.4. NESTED

NESTED 是如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行,所以说 A 和 B 不是同一个事务,那么当 B 的一个方法出现异常时进行回滚,另一个 A 调用的方法是不受影响的,也印证了这两个不是同一个事务,确实是创建了一个嵌套事务

和 REQUIRED 不同的是,那里用的是同一个事务,其中一个回滚,都要回滚,这里可以只是自己的事务进行回滚,也就是实现局部回滚

主页

Read more

GitHub热榜----前端已死?AionUi 横空出世:首个开源“生成式UI”框架,让 AI 在运行时“手搓”界面

GitHub热榜----前端已死?AionUi 横空出世:首个开源“生成式UI”框架,让 AI 在运行时“手搓”界面

摘要:2025 年我们还在惊叹于 V0 和 Bolt 的代码生成能力,而 2026 年初,AionUi 的发布宣告了**“运行时生成 (Runtime GenUI)”**时代的到来。不再需要预先写好所有 Component,不再需要 Hardcode 每一个表单。AionUi 允许你的应用根据用户的意图,实时渲染出从未被编码过的 UI 界面。本文带你上手这个颠覆性的开源项目。 🚀 前言:从“写死”到“生成” 传统前端开发的逻辑是: 产品经理提需求 -> 设计师出图 -> 程序员把 UI 写成代码 (React/Vue) -> 打包发布 -> 用户看到静态界面。

By Ne0inhk
WebGIS开发实战:WKT转GeoJSON的多种技巧与Leaflet加载应用详解

WebGIS开发实战:WKT转GeoJSON的多种技巧与Leaflet加载应用详解

目录 前言 一、WKT后台转换实现 1、基于PostGIS实现 2、GeoTools实现 二、wellknown.js转换 1、wellknown.js是什么? 2、wellknown.js的方法 三、在Leaflet.js中集成wellknow.js 1、资源引入 2、将wkt转为geojson 四、总结 前言         在当今数字化浪潮中,地理信息系统(GIS)技术正以前所未有的速度融入我们的生活与工作。从城市规划到环境监测,从物流配送到旅游出行,地理空间数据的价值日益凸显。而 WebGIS,作为 GIS 技术与 Web 技术的深度融合,更是为地理信息的共享与交互开辟了广阔天地。它让地理数据能够通过网络在各种终端设备上轻松呈现,极大地拓展了 GIS 的应用场景和受众群体。然而,在 WebGIS

By Ne0inhk
Flutter 三方库 async_extension 的鸿蒙化适配指南 - 实现具备高级异步编排算法与流操作扩展的并发工具集、支持端侧复杂业务流的函数式处理实战

Flutter 三方库 async_extension 的鸿蒙化适配指南 - 实现具备高级异步编排算法与流操作扩展的并发工具集、支持端侧复杂业务流的函数式处理实战

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 async_extension 的鸿蒙化适配指南 - 实现具备高级异步编排算法与流操作扩展的并发工具集、支持端侧复杂业务流的函数式处理实战 前言 在进行 Flutter for OpenHarmony 的大规模异步业务系统(如实时行情刷新、多源数据聚合)开发时,如何更优雅地处理 Future 的超时竞争、Stream 的防抖(Debounce)或复杂的并发队列控制?虽然 Dart async 包提供了基础功能,但 async_extension 进一步扩展了异步编程的边界,提供了更符合函数式范式的工具。本文将探讨如何在鸿蒙端构建极致、高效的异步处理链路。 一、原直观解析 / 概念介绍 1.1 基础原理 该库通过对 Dart 核心异步类的非侵入式扩展(Extensions)

By Ne0inhk
做了7年算法开发,我终于把AI、机器学习、深度学习的本质讲透了

做了7年算法开发,我终于把AI、机器学习、深度学习的本质讲透了

入行算法开发7年,从传统风控建模做到工业视觉检测,再到近两年的大模型落地,我见过太多开发者(包括刚入行的自己)被人工智能、机器学习、深度学习这三个概念绕晕。 最常见的误区无非两种:要么把三者混为一谈,觉得“会调YOLO、会跑大模型就是懂AI了”;要么用一句生硬的“AI包含机器学习,机器学习包含深度学习”一笔带过,根本没讲清三者的核心边界、适用场景,以及工业界落地时的选型逻辑。 网上90%的科普文,要么是照搬教科书的空洞定义,要么是AI生成的正确废话,看完还是不知道“做项目的时候到底该用机器学习还是深度学习”。这篇文章我不堆公式、不卷名词,只从一线开发的实战视角,扒透三者的本质区别、落地逻辑,以及我踩过的那些价值几十万的坑。 本文适合:刚入门AI领域的在校生、想转算法的开发工程师、需要做技术选型的项目负责人,以及对AI落地有困惑的从业者。全程干货,无套话,全是实战沉淀。 一、先破误区:三者根本不是简单的“包含关系” 很多人入门时被灌输的第一句话就是“AI>机器学习>深度学习”

By Ne0inhk