当前位置: 首页 > news >正文

Spring -- 事务

Spring中事务的操作分为两类:
(1)编程式事务 – 手动写代码操作事务
(2)声明式事务 – 利用注解开启事务和提交事务

1. 编程式事务

准备Controller


@RestController
@RequestMapping("/user")
public class UserInfoController {@Autowiredprivate UserInfoService userInfoService;@RequestMapping("addUser")public String addUser(UserInfo userInfo) {userInfoService.insert(userInfo);return "SUCCESS";}
}

Spring Boot内置了两个对象
DataSourceTransactionManager事务管理器,用来开始事务,提交或回滚事务
TransactionDefinition是事务的属性,在开启事务的时候需要将TransactionDefinition传递进去从而获得一个事务TransactionStatus

先来看没有事务的执行结果:
访问后:
image.png

如果设置了事务:

@RestController
@RequestMapping("/user")
@Slf4j
public class UserInfoController {//事务管理器@Autowiredprivate DataSourceTransactionManager transactionManager;//定义事务属性@Autowiredprivate TransactionDefinition transactionDefinition;@Autowiredprivate UserInfoService userInfoService;@RequestMapping("/addUser")public String addUser(UserInfo userInfo) {log.info("addUser:{}",userInfo);//开启事务TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);userInfoService.insert(userInfo);//事务提交transactionManager.commit(transactionStatus);return "SUCCESS";}
}

执行结果:
image.png
观察数据库,发现两条数据都有插入:
image.png

如果我们设置了回滚

@RequestMapping("/addUser")
public String addUser(UserInfo userInfo) {
log.info("addUser:{}",userInfo);
//开启事务
TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);userInfoService.insert(userInfo);//事务提交
transactionManager.rollback(transactionStatus);
return "SUCCESS";
}

image.png
对比发现,如果是成功提交,输出的日志是
image.png
如果回滚了,输出的日志是没有这一条信息的,并且数据库也不会更新

但是如果此时我们再次提交事务:
image.png
查看数据库的数据:
image.png
中间空着的id为17的数据就是我们刚刚回滚的操作

2. Spring声明式事务@Transactional

声明式事务的实现需要两步:

2.1 添加依赖

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

2.2 添加@Transactional注解

在需要添加事务的地方加上@Transactional注解即可,无需手动开启事务和提交事务
如果中途发生了没有处理的异常会回滚事务

正常情况:

@RestController
@RequestMapping("/user1")
@Slf4j
public class UserInfoController1 {@Autowiredprivate UserInfoService userInfoService;@Transactional@RequestMapping("/addUser1")public String addUser(UserInfo userInfo) {log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);return "SUCCESS";}
}

image.png

异常情况:

@Transactional
@RequestMapping("/addUser1")
public String addUser(UserInfo userInfo) {
log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);
int a = 10/0;//出现未处理的异常
return "SUCCESS";
}

image.png
此时会自动回滚,没有提交
但是如果异常在方法内被处理了,就会提交事务

@Transactional
@RequestMapping("/addUser1")
public String addUser(UserInfo userInfo) {
log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);
try {int a = 10/0;
} catch (Exception e) {e.printStackTrace();
}
return "SUCCESS";
}

image.png
我们可以在catch里面手动进行回滚事务:

@Transactional
@RequestMapping("/addUser1")
public String addUser(UserInfo userInfo) {
log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);
try {int a = 10/0;
} catch (Exception e) {e.printStackTrace();TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return "SUCCESS";
}

再次访问:不会提交
image.png

注意:@**Transactional**** **注解可以用来修饰方法或类:

  • 修饰方法时,只有修饰public方法时才生效(修饰其他方法时不会报错,但是不会生效)
  • 修饰类时,类中所有的public方法都会生效
@Transactional
@RequestMapping("/addUser1")
public String addUser(UserInfo userInfo) {
log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);
try {int a = 10/0;
} catch (Exception e) {e.printStackTrace();TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return "SUCCESS";
}

2.3 @Transactional详解

@Transactional有三个重要的属性:

2.3.1 rollbackFor

@Transactional默认只是在遇到运行时异常以及Error时才会回滚,非运行时异常不会回滚

@Transactional
@RequestMapping("/addUser1")
public String addUser(UserInfo userInfo) throws IOException {log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);if (true) {throw new IOException();}return "SUCCESS";
}

访问:
image.png
事务是会提交的
如果我们需要对所有的异常都回滚,需要配置@Transactional注解当中的rollbackFor属性指定出现何种异常时事务进行回滚

@Transactional(rollbackFor = Exception.class)
@RequestMapping("/addUser1")
public String addUser(UserInfo userInfo) throws IOException {log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);if (true) {throw new IOException();}return "SUCCESS";
}

再次访问:事务不会提交
image.png

2.3.2 事务隔离级别

MySQL事务隔离级别

SQL定义了四种隔离级别:

  1. 读未提交:该隔离级别的事务可以看到其他事务中未提交的数据

其他事务未提交的数据可能会发生回滚,但是该隔离级别的事务可以读到,我们吧该级别读到的数据称为脏数据,这个问题称为脏读

  1. 读已提交:该隔离级别的事务能读取到已经提交事务的数据

该隔离级别不会有脏读的问题,但是由于在事务的执行过程中可以读取到其他事务提交的结果,所以在不同时间相同的sql查询可能会读到不同的结果,这种现象叫做不可重复读

  1. 可重复读:事务不会读到其他事务对已有数据的修改,即使其他事务已经提交,也可以确保

在同一事务多次查询的结果是一致的,但是其他事务新插入的数据,是可以感知到的,这也就引发了幻读问题.可重复读是MySQL默认的事务隔离级别

  1. 串行化:序列化,事务最高的隔离级别,他会强制事务排序,使之不会产生冲突,从而解决

脏读,不可重复读和幻读问题,但是执行效率低,使用场景不多

Spring事务隔离级别

Spring中事务隔离级别有5种

  1. Isolatio.DEFAULT以连接的数据库的事务隔离级别为主
  2. Isolation.READ_UNCOMMITTED:读未提交,对应SQL标准中的读未提交
  3. Isolation.READ_COMMITTED: 读已提交,对应SQL标准中的读已提交
  4. Isolation.REPEATABLE_READ:可重复读.对应SQL标准中的可重复读
  5. Isolation.SERIALIZABLE:串行化,对应SQL标准中的串行化

image.png
Spring中事务隔离级别可以通过@Transactional中的Isolation属性进行设置

@Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_UNCOMMITTED)
@RequestMapping("/addUser1")
public String addUser(UserInfo userInfo) throws IOException {log.info("addUser:{}",userInfo);userInfoService.insert(userInfo);return "SUCCESS";
}

2.3.3 事务传播机制

事务传播机制就是,多个事务之间存在调用关系时,事务是如何在这些方法间进行传播的
比如A方法调用B方法,A执行时,会开启一个事务,B本身也存在一个事务,此时B的事务是加入A的事务,还是创建一个新的事务
这就涉及到了事务传播机制
@Transactional注解支持事务传播机制的设置,通过propagation属性来指定传播行为

  1. Propagation.REQUIRED:默认的事务传播级别.表示如果当前存在事务,则加入该事务.如果当前没有事务,则创建一个事务
  2. Propagation.SUPPORTS:如果当前存在事务,则加入事务;如果当前没有存在事务,则以非事务的方式继续进行
  3. Propagation.MANDATORY:强制性,如果当前存在事务,则加入事务,如果当前没有事务,则抛出异常
  4. Propagation.REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起,也就是说不管外部方法是否开启事务,Propagation.REQUIRES_NEW修饰的内部方法都会新开自己的事务,且开启的事务相互独立,互不干扰
  5. Propagation.NOT_SUPPORTED以非事务的方式运行,如果当前存在事务,则把当前的事务挂起
  6. Propagation.NEVER以非事务的方式运行,如果当前存在事务,则抛出异常
  7. Propagation.NESTED如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果没有事务,则该取值等价于Propagation.REQUIRED

我们通过代码来演示一下区别:
(1)REQUIRED
image.png
此时由于是REQUIRED,那么三个方法针对的是同一个事务,只要其中有一个出现异常,都会回滚
image.png
image.png
(2)REQUIRES_NEW
image.png
在这种条件下,事务之间是独立的,因此互不影响
image.png
此时user的事务提交了,但是log的事务回滚了

(3)NEVER
image.png
如果存在事务,那就抛出异常
image.png

(4) NESTED
我们先来看看REQUIRED如果方法都执行成功的情况下:
image.png
如果是NESTED,方法都执行成功的情况下:
image.png
image.png
可以发现是等价的,同样是只是开启了一次事务

如果发生了异常
对于REQUIRED方法:

如果是NESTED
image.png
事务都是全部回滚
看似两种好像都是一样的,实际上存在差别
REQUIRED是加入,而NESTED是嵌套
我们通过以下代码就能很好的看出两种的区别:
image.png
对于NESTEDE:
image.png
image.png
但是对于REQUIRED:
image.png
数据库两个表都没有新增数据
可以注意到,在REQUIRED里面,由于是同一个事务,因此不能部分回滚

相关文章:

Spring -- 事务

Spring中事务的操作分为两类:(1)编程式事务 – 手动写代码操作事务(2)声明式事务 – 利用注解开启事务和提交事务 1. 编程式事务 准备Controller RestController RequestMapping("/user") public class UserInfoController {Autowiredprivate UserInfoService use…...

生命密码的破译者:AI如何学会读懂DNA语言?

引言 如果能像解读一本神秘的书籍那样&#xff0c;理解DNA的“语言”&#xff0c;将是多么令人兴奋的科学突破&#xff01;如今&#xff0c;这正在逐步变为现实。科学家们训练出的AI模型GROVER正如一个勤奋的学生&#xff0c;学习着DNA的每一个“单词”和“语法”&#xff0c;…...

大数据信用报告查询哪家平台的比较好?

相信在搜索大数据信用的你&#xff0c;已经因为大数据信用不好受到了挫折&#xff0c;想详细了解一下自己的大数据信用&#xff0c;但是找遍了网络上的平台之后才发现&#xff0c;很多平台都只提供查询服务&#xff0c;想要找一个专业的平台查询和讲解很困难。下面本文就为大家…...

Java高级Day24-集合最后补充

75.HashTable 基本介绍&#xff1a; 存放元素的健值对 即K-V hashtable的键和值都不能为null&#xff0c;否则会抛出NullPointerException hashtable使用方法基本上和HashMap一样 hashtable是线程安全的&#xff0c;hashmap是线程不安全 扩容机制&#xff1a; 底层有数组…...

C++入门:C语言到C++的过渡

前言&#xff1a;C——为弥补C缺陷而生的语言 C起源于 1979 年&#xff0c;当时 Bjarne Stroustrup 在贝尔实验室工作&#xff0c;面对复杂软件开发任务&#xff0c;他感到 C 语言在表达能力、可维护性和可扩展性方面存在不足。 1983 年&#xff0c;Bjarne Stroustrup 在 C 语言…...

了解MVCC

概念 MVCC&#xff0c;全称Multi-Version Concurrency Control&#xff0c;即多版本并发控制&#xff0c;是一种并发控制的方法&#xff0c;维护一个数据的多个版本&#xff0c;使得读写操作没有冲突&#xff0c;快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现…...

WPF自定义控件的应用(DynamicResource的使用方法)

1 DynamicResource的使用方法 可以在字典文件 的抬头区写入数&#xff1a; <SolidColorBrush x:Key"PrimaryBackgroundColor" Color"#FFABAdB3"/><SolidColorBrush x:Key"TextBox.MouseOver.Border" Color"#FF7EB4EA"/>&l…...

Postgresql数据库密码忘记的解决

当您忘记PostgreSQL数据库的密码时,可以通过以下步骤来重置密码。这些步骤在Windows和Linux操作系统上大体相同,但具体操作路径和命令可能有所不同。 步骤一:找到并修改pg_hba.conf文件 定位安装目录: Windows:通常在PostgreSQL的安装目录下的data文件夹中。Linux:位置可…...

Flink SQL 基础操作

Flink SQL是建立在Apache Flink之上的SQL处理引擎&#xff0c;它允许用户以SQL的方式处理流数据和批数据。以下是一些Flink SQL的基础操作&#xff1a; 一、环境准备 1.启动flink集群 ./start-cluster.sh启动sql-client ./sql-client.sh二、数据源定义 创建表&#xff08;…...

海思AE模块Lines_per_500ms参数的意义

​ 基础知识 1秒(S)1000毫秒(ms)1000_000微妙(s)1000_000_000纳秒(ns) 1GHz1000Mhz1000_000KHz1000_000_000Hz 1Hz1/s 抗频闪原理 海思AE模块参数中有一个LinesPer500ms的参数&#xff0c;意思为500ms对应的曝光行数。此个参数和抗频闪有关。 我们知道&#xff1a; 50HZ…...

【代码随想录】区间和——前缀和方法

本博文为《代码随想录》学习笔记&#xff0c;原文链接&#xff1a;代码随想录 题目 原题链接&#xff1a;58. 区间和&#xff08;第九期模拟笔试&#xff09; 题目描述 给定一个整数数组 Array&#xff0c;请计算该数组在每个指定区间内元素的总和。 输入描述 第一行输入为…...

Bug 解决 | 前端项目无法正确安装依赖?

目录 1、网络问题 2、权限问题 3、版本冲突 4、缓存问题 5、依赖配置错误 6、系统环境问题 前端项目和后端项目一样&#xff0c;都需要用到很多第三方的类库依赖。目前基本上我们主流的前端项目都使用 Npm、Yarn 等包管理工具来管理项目依赖&#xff0c;正常情况下通过执…...

【mysql 第四篇章】bin log 的作用是啥呢?

一、redo Log 介绍 redo log 是一种偏向物理性质的重做日志&#xff0c;因为他里面记录类似的这样的东西&#xff0c;“对那个数据也中的什么记录&#xff0c;做了个什么修改”。它是 InnoDB 存储引擎特有的东西。 二、bin Log 日志 bin log 叫做归档日志&#xff0c;它里面…...

Linux 操作系统:基于环形队列的生产者消费者模型

Linux 操作系统&#xff1a;基于环形队列的生产者消费者模型 一、前言二、大致框架二、P操作、V操作三、生产者生产数据四、生产者获取数据五、代码测试六、所有代码 一、前言 环形队列采用数组模拟&#xff0c;用模运算来模拟环状特性。和基于阻塞队列的生产者消费者模型不同的…...

python求解二次方程

为了找到x和y之间的关系&#xff0c;并假设这种关系是一个二次函数&#xff0c;我们可以使用numpy的polyfit函数来拟合一个二次方程&#xff08;即形式为y ax^2 bx c的方程&#xff09;。然后&#xff0c;我们可以使用matplotlib来绘制散点图&#xff0c;并在图上添加最佳拟…...

Spring框架面试总结

Spring基础 什么是spring框架 Spring 框架是一个用于构建企业级 Java 应用程序的开源框架。【Java项目快速构建轻量级框架】我们一般说 Spring 框架指的都是 Spring Framework&#xff0c;它是很多模块的集合&#xff0c;使用这些模块可以很方便地协助我们进行开发。【根据模…...

java之网络编程篇

前言 网络编程就是计算机和计算机之间通过网络进行数据传输&#xff0c;下面介绍一些概念和如何实现UDP和TCP两种模式的传输。 一、常见的软件架构C/S和B/S C/S架构需要一个客户端软件程序服务器 B/S只需要打开网页服务器 C/S架构的优缺点和应用场景 优点&#xff1a;画面可以…...

stm32f103c8t6与TB6612FNG解耦测试

stm32f103c8t6与TB6612FNG解耦测试 本文操作方式: 忽略底层,只做上层, 所以前面全部照搬步骤,重在调试 文章目录 stm32f103c8t6与TB6612FNG解耦测试本文操作方式:创建基本工程(1)跳转此链接,创建(2)创建电机驱动文件夹(3)PWM原理(4)电机转动控制 oled调试和key调试(5)OLED转速…...

2253336 - 资源库 - OAC0 中的脱机状态

症状 资源库的状态显示为离线。 环境 SAP 内容服务器 6.50 或更高版本与 MaxDB 存储媒介结合使用对于状态为离线的资源库&#xff0c;测试报表 RSCMST 运行正常资源库可在应用程序中使用&#xff0c;没有任何问题 重现问题 启动事务 OAC0双击资源库按 "CSADMIN"…...

uni-app总结

1. <u-form-item label"报废人" ><u--input v-model"model.remark" border"bottom" placeholder"请输入"></u--input> </u-form-item> border"bottom" 报废日期 为了...

intv_ai_mk11零基础上手:不装软件、不写代码、不开终端,纯浏览器操作

intv_ai_mk11零基础上手&#xff1a;不装软件、不写代码、不开终端&#xff0c;纯浏览器操作 1. 为什么选择intv_ai_mk11 想象一下&#xff0c;你正在准备一份重要报告&#xff0c;突然需要一段专业的内容摘要&#xff1b;或者你在写营销文案时卡壳了&#xff0c;需要一些创意…...

Verilog基础:task和function的使用(一)

相关文章 Verilog基础专栏https://blog.csdn.net/weixin_45791458/category_12263729.html 一、前言 任务(task)和函数(function)即提供了从不同位置执行公共过程的能力&#xff08;因为这样可以实现代码共享&#xff09;&#xff0c;也提供了把大过程分解成小过程的能力&…...

多模态情报分析awesome-osint:文本图像视频融合处理终极指南

多模态情报分析awesome-osint&#xff1a;文本图像视频融合处理终极指南 开源情报&#xff08;OSINT&#xff09;正在经历一场革命性的变革&#xff0c;而awesome-osint项目正是这场变革的引领者。这个精心策划的资源集合汇集了最先进的多模态情报分析工具&#xff0c;让你能够…...

ESP-01 AT固件烧录实战:从接线到调试的完整指南

1. 认识ESP-01模块与AT固件 如果你手头正好有个积灰的ESP-01模块&#xff0c;想用它来做点物联网小项目&#xff0c;那首先要解决的就是固件问题。这个指甲盖大小的WiFi模块出厂时可能不带AT指令集&#xff0c;或者固件版本太旧需要升级。我去年整理实验室时就翻出十几个不同批…...

完整B站字幕提取解决方案:三步搞定视频字幕获取与转换

完整B站字幕提取解决方案&#xff1a;三步搞定视频字幕获取与转换 【免费下载链接】BiliBiliCCSubtitle 一个用于下载B站(哔哩哔哩)CC字幕及转换的工具; 项目地址: https://gitcode.com/gh_mirrors/bi/BiliBiliCCSubtitle 你是否曾经在B站看到精彩的教学视频&#xff0c…...

KeyboardChatterBlocker:如何解决机械键盘的“幽灵按键“问题?

KeyboardChatterBlocker&#xff1a;如何解决机械键盘的"幽灵按键"问题&#xff1f; 【免费下载链接】KeyboardChatterBlocker A handy quick tool for blocking mechanical keyboard chatter. 项目地址: https://gitcode.com/gh_mirrors/ke/KeyboardChatterBlocke…...

LTR-329ALS-01环境光传感器驱动与I²C配置详解

1. LTR-329ALS-01 数字环境光传感器深度技术解析1.1 器件定位与系统级设计考量LTR-329ALS-01 是一款面向低功耗嵌入式应用的 IC 接口数字环境光传感器&#xff08;Ambient Light Sensor, ALS&#xff09;&#xff0c;由 Lite-On 公司设计&#xff0c;广泛应用于智能手机、可穿戴…...

Phi-4-mini-reasoningGPU算力适配:A10/A100/T4多卡环境下的推理吞吐调优

Phi-4-mini-reasoning GPU算力适配&#xff1a;A10/A100/T4多卡环境下的推理吞吐调优 1. 模型特性与部署概述 Phi-4-mini-reasoning 是一款专注于推理任务的文本生成模型&#xff0c;特别擅长处理数学题、逻辑题等需要多步分析和简洁结论输出的场景。与通用聊天模型不同&…...

AgentCPM-Report部署教程:Pixel Epic在Ubuntu/CentOS下的环境配置

AgentCPM-Report部署教程&#xff1a;Pixel Epic在Ubuntu/CentOS下的环境配置 1. 项目介绍 Pixel Epic是一款基于AgentCPM-Report大模型构建的研究报告辅助终端&#xff0c;它将枯燥的科研工作转化为一场像素风格的RPG冒险体验。与传统AI工具不同&#xff0c;Pixel Epic采用了…...

告别编译报错!Termux安装Pandas最稳方案实测(附Matplotlib、Numpy、Scipy一键配置清单)

Termux科学计算环境搭建&#xff1a;零报错安装Pandas与数据三件套实战指南 在移动端进行Python数据分析曾是天方夜谭&#xff0c;直到Termux的出现打破了这一限制。但许多用户在安装Pandas、Numpy、Scipy和Matplotlib这组"数据科学四件套"时&#xff0c;总会遇到各种…...