【JavaEE】Spring事务
目录
- 一、事务简介
- 二、Spring事务的实现
- 2.1 事务的操作
- 2.2 分类
- 2.2.1 Spring编程式事务
- 2.2.2 Spring 声明式事务 @Transactional
- 2.2.2.1 @Transactional 详解
- 2.2.2.1.1 rollbackFor
- 2.2.2.1.2 Isolation
- 2.2.2.1.3 propagation

一、事务简介
事务:事务是⼀组操作的集合,是⼀个不可分割的操作。事务会把所有的操作作为⼀个整体,⼀起操作。所以这组操作要么同时成功,要么同时失败。
二、Spring事务的实现
2.1 事务的操作
事务的操作主要有三步:
- 开启事start transaction / begin (⼀组操作前开启事务)
- 提交事务: commit (这组操作全部成功,提交事务)
- 回滚事务: rollback (这组操作中间任何⼀个操作出现异常,回滚事务)
2.2 分类
Spring 中的事务操作分为两类:
- 编程式事务(⼿动写代码操作事务)
- 声明式事务(利⽤注解⾃动开启和提交事务)
2.2.1 Spring编程式事务
SpringBoot 内置了两个对象:
DataSourceTransactionManager
事务管理器。⽤来获取事务(开启事务),提交或回滚事务TransactionDefinition
是事务的属性,在获取事务的时候需要将 TransactionDefinition 传递进去从⽽获得⼀个事务 TransactionStatus
示例:
package com.example.springtransdemo.controller;import com.example.springtransdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/user")
@RestController
public class UserController {@Autowiredprivate UserService userService;//事务属性@Autowiredprivate TransactionDefinition definition;//事务管理器@Autowiredprivate DataSourceTransactionManager transactionManager;@RequestMapping("/registry")public String registry(String name,String password) {//开启事务TransactionStatus transaction = transactionManager.getTransaction(definition);//⽤⼾注册userService.registryUser(name, password);//提交事务transactionManager.commit(transaction);//回滚事务//transactionManager.rollback(transaction);return "注册成功";}
}
当我们不提交时可以在数据库中添加字段,回滚后就不会在数据库中添加字段,提交和回滚方法不能在同一个事务中调用。
2.2.2 Spring 声明式事务 @Transactional
使用这个注解需要添加依赖,但是如果已经添加了MyBatis的依赖,那么就包含了下面需要引入的依赖的内容。
<dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId>
</dependency>
注解的应用,在需要使用到事务的方法上加上注解,就会自动提交事务状态。当发⽣了没有处理的error和RunTimeException异常(默认情况下)的时候,就会自动回滚。
例如上面的代码就可以改为:
@RequestMapping("/registry")@Transactionalpublic String registry(String name,String password) {//⽤⼾注册userService.registryUser(name, password);return "注册成功";}
那么当我们就是要在捕获处理了异常后,还是将事务进行回滚时,我们就可以手动回滚使用TransactionAspectSupport
类下使用currentTransactionStatus
方法获取状态,使用isRollbackOnly
方法回滚。
@RequestMapping("/registry")@Transactionalpublic String registry(String name,String password) {//⽤⼾注册userService.registryUser(name, password);try{int a = 10 / 0;} catch (Exception e) {log.error("错误");TransactionAspectSupport.currentTransactionStatus().isRollbackOnly();}return "注册成功";}
2.2.2.1 @Transactional 详解
修饰范围:
- 修饰类时,就是修饰类中的所用访问修饰限定符为
public
的方法。 - 修饰方法时,只能修饰访问修饰限定符为
public
的方法。
@Transactiona 常见三大属性:
- rollbackFor:异常回滚属性。指定能够触发事务回滚的异常类型。可以指定多个异常类型。
- Isolation:事务的隔离级别。默认值为 Isolation.DEFAULT。
- propagation:事务的传播机制。默认值为 Propagation.REQUIRED 。
2.2.2.1.1 rollbackFor
@Transactional 默认只在遇到运⾏时异常RunTimeException和Error时才会回滚。
例如执行下面的操作的时候,事务不会回滚,数据库中还是会添加数据。
@RequestMapping("/registry")@Transactionalpublic String registry(String name,String password) throws IOException {//⽤⼾注册userService.registryUser(name, password);if(true) {throw new IOException();}return "注册成功";}
但是我们加上属性rollbackFor就会在发生rollbackFor指定的异常的时候回滚。
@RequestMapping("/registry")@Transactional(rollbackFor = Exception.class)public String registry(String name,String password) throws IOException {//⽤⼾注册userService.registryUser(name, password);if(true) {throw new IOException();}return "注册成功";}
还有与rollbackFor相似作用的属性:
- rollbackFor :使用class作为值,在发生该异常的时候回滚。
- rollbackForClassName:使用类名作为值,在发生该异常的时候回滚。
- noRollbackFor :使用class作为值,在发生该异常的时候不回滚。
- noRollbackForClassName:使用类名作为值,在发生该异常的时候不回滚。
当我们同时使用@Transactionsl的noRollbackFor和rollbackFor对同一异常类处理,后使用的会覆盖前面的。例如@Transactional(rollbackFor = IOException.class, noRollbackFor = IOException.class)
生效的是noRollbackFor = IOException.class
。
2.2.2.1.2 Isolation
Spring事务的隔离级别有以下几种值:
- DEFAULT:数据库是什么隔离级别,这个方法就还是什么隔离级别。
剩下的都对应MySQL的隔离级别。
- 读未提交(READ_UNCOMMITTED):读未提交,也叫未提交读。该隔离级别的事务可以看到其他事务中
未提交的数据,会有脏读问题。 - 读提交(READ_COMMITTED):读已提交,也叫提交读。该隔离级别的事务能读取到已经提交事务的数据,该隔离级别不会有脏读的问题。
- 可重复读(REPEATABLE_READ):事务不会读到其他事务对已有数据的修改,即使其他事务已提交。也就可以确保同⼀事务多次查询的结果⼀致,但是其他事务新插⼊的数据,是可以感知到的,这也就引发了幻读问题。
- 串⾏化(SERIALIZABLE):序列化,事务最⾼隔离级别。它会强制事务排序,使之不会发⽣冲突,从⽽解
决了脏读,不可重复读和幻读问题,但因为执⾏效率低,所以真正使⽤的场景并不多。
2.2.2.1.3 propagation
事务的传播机制有以下七种。
我们以A方法调用B方法为例解释:
- Propagation.REQUIRED :默认的事务传播级别,如果当前存在事务,则加⼊该事务,如果当前没有事务,则创建⼀个新的事务。如果A方法有事务,B直接就加入,A没有事务B创建一个事务。
- Propagation.SUPPORTS :如果当前存在事务,则加⼊该事务。如果当前没有事务,则以⾮事务的⽅式继续运⾏。如果A方法有事务,B直接就加入,A没有事务B也没有事务。
- Propagation.MANDATORY :强制性。如果当前存在事务,则加⼊该事务。如果当前没有事务,则抛出异常。如果A方法有事务,B直接就加入,A没有事务抛异常。
- Propagation.REQUIRES_NEW :创建⼀个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部⽅法是否开启事务,Propagation.REQUIRES_NEW 修饰的内部⽅法都会新开启⾃⼰的事务,且开启的事务相互独⽴,互不⼲扰。如果A方法有事务,B创建一个事务,两个事务互不影响,A没有事务,B也会创建一个事务。
- Propagation.NOT_SUPPORTED :以⾮事务⽅式运⾏,如果当前存在事务,则把当前事务挂起(不⽤)。如果A方法有事务,B创建一个事务,使用B创建的事务,A没有事务B也没有。
- Propagation.NEVER :以⾮事务⽅式运⾏,如果当前存在事务,则抛出异常。如果A方法有事务,抛异常,A没有事务B也没有。
- Propagation.NESTED :如果当前存在事务,则创建⼀个事务作为当前事务的嵌套事务来运⾏。如果当前没有事务,则该取值等价于 PROPAGATION_REQUIRED 。如果A方法有事务,B创建一个事务,A的事务相当于B的父事务,A没有事务,B也会创建一个事务。
传播行为 | 当前有事务 | 当前无事务 |
---|---|---|
REQUIRED | 加入事务 | 新建事务 |
SUPPORTS | 加入事务 | 非事务执行 |
MANDATORY | 加入事务 | 抛出异常 |
REQUIRES_NEW | 挂起当前事务并新建事务 | 新建事务 |
NOT_SUPPORTED | 挂起当前事务并以非事务执行 | 非事务执行 |
NEVER | 抛出异常 | 非事务执行 |
NESTED | 创建嵌套事务 | 新建事务 |
相关文章:

【JavaEE】Spring事务
目录 一、事务简介二、Spring事务的实现2.1 事务的操作2.2 分类2.2.1 Spring编程式事务2.2.2 Spring 声明式事务 Transactional2.2.2.1 Transactional 详解2.2.2.1.1 rollbackFor2.2.2.1.2 Isolation2.2.2.1.3 propagation 一、事务简介 事务:事务是⼀组操作的集合…...
Flink 状态管理深度解析:类型与后端的全面探索
在流处理场景中,数据往往是连续且无界的,为了准确处理这些数据并维持计算的连续性,Flink 引入了状态管理机制。Flink 的状态管理包含状态类型和状态后端两大部分,它们相辅相成,共同为作业的可靠性、容错性和性能提供保障。接下来,我们将深入探究 Flink 状态管理中状态类型…...

Android15 userdebug版本不能remount
背景描述: 最近调试Android Vendor Hal的时候发现一个奇怪的现象: android userdebug版本刷到设备中,执行adb root没提示错误,但是没有获取到root权限。 Android设备运行的系统版本有三种情况:user版本、userdebug版本和eng版本…...

R包安装报错解决案例系列|R包使用及ARM架构解决data.table安装错误问题
有不少同学是Mac系统的,分析过程中会发现部分R包总是安装不成功,这是因为部分R包基于windowsx86架构编译的,最常见的就是含 C/C/Fortran 的包,对于初学者都是建议linux和win去做,Windows 通常直接安装预编译好的二进制…...
k8s Headless Service
Kubernetes 无头服务(Headless Service)配置与使用场景 1.无头服务概述 无头服务(Headless Service)是 Kubernetes 中的一种特殊服务类型,它**不分配集群 IP(ClusterIP),而是直接暴露…...

Linux上安装MongoDB
目录 一、在Linux系统安装MongoDB服务器 1、下载MongoDB 2、上传MongoDB并解压 3、创建必要目录 4、配置环境变量 5、创建配置文件 6、启动命令 7、验证安装 二、在Linux系统安装MongoDB客户端Shell 1、下载MongoDB Shell 2、上传MongoDB Shell并解压 3、配置环境变…...

Redis最佳实践——安全与稳定性保障之访问控制详解
Redis 在电商应用的安全与稳定性保障之访问控制全面详解 一、安全访问控制体系架构 1. 多层级防护体系 #mermaid-svg-jpkDj2nKxCq9AXIW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-jpkDj2nKxCq9AXIW .error-ico…...

【华为开发者空间 x DeepSeek】服务器运行Ollama并在本地调用
文章概述 本文介绍了如何在 华为开发者空间 中快速部署并使用 Ollama 模型运行框架,并结合 deepseek-r1 模型进行本地或远程交互推理。内容涵盖环境准备、模型配置、网卡绑定、内网穿透、API调用等多个环节,适合希望在华为云上快速搭建本地类大模型推理…...
Halcon
regiongrowing — Segment an image using regiongrowing. get_obj_class:获取图像的类别名 get_region_points:获取区域的像素 get_contour_xld:获取xld像素点坐标 get_polygon_xld:获取多边形的数据 get_region_polygon:计算一个区域的…...

STM32之IIC(重点)和OLED屏
内部集成电路概述 基本概念 内部集成电路(Inter Integrated Circuit)的简称叫做IIC或者I2C,是一种简单的、半双工同步通信的串行通信接口,IIC总线是上世纪80年代(1982年)由飞利浦公司设计出来,…...

学习海康VisionMaster之表面缺陷滤波
一:进一步学习了 今天学习下VisionMaster中的表面缺陷滤波:简单、无纹理背景的表面缺陷检测,可以检测表面的异物,缺陷,划伤等 二:开始学习 1:什么表面缺陷滤波? 表面缺陷滤波的核心…...

游戏引擎学习第314天:将精灵拆分成多个层
回顾并为今天的工作做准备 我们今天继续昨天开始的工作,现在我们要回到渲染中处理 Z 值的最终环节。我们目前已经有一个我们认为还算合理的排序方式,虽然可能还需要在接下来的过程中进行一些调整,但总体上已经有了一个明确的方向。 我们已经…...

【学习笔记】深度学习-梯度概念
一、定义 梯度向量不仅表示函数变化的速度,还表示函数增长最快的方向 二、【问】为什么说它表示方向? 三、【问】那在深度学习梯度下降的时候,还要判断梯度是正是负来更新参数吗? 假设某个参数是 w,损失函数对它的…...

【数据结构】图的存储(邻接矩阵与邻接表)
图的存储结构 因为图中既有节点,又有边(节点与节点之间的关系),因此,在图的存储中,只需要保存:节点和边关系即可。 节点保存比较简单,只需要一段连续空间即可,那边关系该怎么保存呢࿱…...

tomcat yum安装
使用yum安装 yum install -y java-1.7.0-openjdk* tomcat* --disablerepoepel## java-1.7.0-openjdk* 注意:最终安装的是java-1.8.0版本## --disablerepoepel 禁用:EPEL源,防止版本冲突 java -version (2) 启停:Tomcat 7 s…...
【Elasticsearch】suggest_mode
suggest_mode 是 Elasticsearch 中 term suggester 和 phrase suggester 的一个参数,用于控制建议的生成方式。它有以下三种模式: 1. missing:默认值。仅对索引中不存在的词项提供建议。如果输入的词已经在索引中存在,则不会生成建…...
数据库只更新特定字段的两种方式(先读后写 vs. 动态组织 SQL)-golang SQLx 实现代码(动态组织 SQL)
文章目录 数据库只更新特定字段的两种方式(先读后写 vs. 动态组织 SQL)go语言例子使用GORM的示例(最常用的Go ORM库)使用SQLx的两种更新方式实现golang SQLx 实现代码(动态组织 SQL) 数据库只更新特定字段的…...

从翻译后修饰角度解析人工合成途径与底盘细胞的适配性-文献精读136
Compatibility between synthetic pathway and chassis cells from the viewpoint of post-translational modifications 从翻译后修饰角度解析人工合成途径与底盘细胞的适配性 摘要 揭示工程化设计的人工合成途径与底盘细胞整体代谢网络的交互作用及适配性机制是合成生物学研…...

Cesium快速入门到精通系列教程一
一、打造第一个Cesium应用 1、官方渠道下载Cesium(可选择历史版本) GitHub Releases页面 访问 Cesium GitHub Releases,此处列出了所有正式发布的版本。 通过标签(如 v1.95.0)选择目标版本,下载…...

[Windows] 剪映 视频编辑处理
附链接:夸克网盘分享(点击蓝色字体自行保存下载)...

决策树 GBDT XGBoost LightGBM
一、决策树 1. 决策树有一个很强的假设: 信息是可分的,否则无法进行特征分支 2. 决策树的种类: 2. ID3决策树: ID3决策树的数划分标准是信息增益: 信息增益衡量的是通过某个特征进行数据划分前后熵的变化量。但是&…...

stm32 / arduino TPL0401A使用教程
这是在给英国的一个学生讲课时用到的一个芯片,做一个dcdc的反馈电路,刚开始用的不是这个,后来发现国内这个芯片用的挺成熟,就选择了这个。 芯片说明 首先我买的是TPL0401A,我发现淘宝上卖的都是A,其实想用C࿰…...

数据结构与算法之单链表面试题(新浪、百度、腾讯)
单链表面试题(新浪、百度、腾讯) 求单链表中的有效节点的个数 public int getCount(HeroNode head) {Hero1 cur head.getNext();int count 0;while(cur ! null) {count;cur cur.getNext();}return count;}查找单链表中的倒数第k个结点【新浪面试题】…...

单板机8088C语言计划
计划将原来用汇编写的小程序,用C语言重新写一遍 计划2个月能完成 然后再试试,能不能用C写一下固件BootLoad 和一个类似Dos时代的Debug调试器...

一周学会Pandas2之Python数据处理与分析-数据重塑与透视-pivot() - 透视 (长 -> 宽,有限制)
锋哥原创的Pandas2 Python数据处理与分析 视频教程: 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili pivot() 是 pandas 中用于数据重塑的核心方法,它将长格式数据转换为宽格式数据,与 melt() 方…...

机器学习中无监督学习方法的聚类:划分式聚类、层次聚类、密度聚类
1.定义和特点 2.划分式聚类:K-Means 、 K-Medoids 3.层次聚类:树状图 4.密度聚类:DBSCAN 5.聚类的应用 一、定义和特点 机器学习中的无监督学习聚类是一种通过数据内在结构将样本分组的技术,无需预先标注的类别标签。 它的核心目…...

【HW系列】—溯源与定位—Linux入侵排查
文章目录 一、Linux入侵排查1.账户安全2.特权用户排查(UID0)3.查看历史命令4.异常端口与进程端口排查进程排查 二、溯源分析1. 威胁情报(Threat Intelligence)2. IP定位(IP Geolocation)3. 端口扫描&#x…...

CPO-BP+MOPSO,冠豪猪优化BP神经网络+多目标粒子群算法!(Matlab源码)
目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.CPO-BPNSGA,冠豪猪优化BP神经网络粒子群算法!(Matlab完整源码和数据),冠豪猪算法优化BP神经网络的权值和阈值,运行环境Matlab2020b及以上。 多…...

模块化设计,static和extern(面试题常见)
文章目录 一、函数的声明和定义1.1 单个文件1.2 多个文件1.3 static和extern1.3.1 static修饰局部变量1.3.2 static修饰全局变量1.3.3 static修饰函数 总结 一、函数的声明和定义 1.1 单个文件 一般我们在使用函数的时候,直接将函数写出来就使用了 题目:写一个函数…...

【快速解决】数据库快速导出成sql文件
1、cmd直接打开 输入命令 mysqldump -u用户名 -p密码 数据库名 > 导出文件名.sql修改成自己mysql的用户名和密码,和要导出的数据库名称,给导出的文件起一个名字。 如图所示 这样就成功了。...