Spring实现事务二

.

在这里插入图片描述

上一次我们讲到,Spring实现事务的方式有两种,并且,为实现这两种方式,我们做了一些准备工作,那么接下来,我将带着大家,来继续学习事务的相关知识

编程式事务

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

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;@RestController
public class UserInfoController {@Autowiredprivate UserInfoService userInfoService;@Autowired// JDBC 事务管理器private DataSourceTransactionManager dataSourceTransactionManager;@Autowired// 定义事务属性private TransactionDefinition transactionDefinition;@RequestMapping("/login")public String login(String userName,String password){//开启事务TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);Integer result = userInfoService.insert(userName,password);//提交事务dataSourceTransactionManager.commit(transactionStatus);//回滚事务
//        dataSourceTransactionManager.rollback(transactionStatus);if(result<=0){return  "添加失败";}else {return "添加成功";}}
}

运行程序: http://127.0.0.1:8080/login?userName=zhangsan&password=123456
可以看到,当我们的代码中使用事务提交的时候,数据库中确实被插入了userName=zhangsan&password=123456,但是如果采用事务回滚,那么既是打印的日志显示插入成功,数据库中却并没有新增数据

声明式事务@Transactional


@RestController
public class UserInfoController2 {@Autowiredprivate UserInfoService userInfoService;@Transactional( isolation = READ_COMMITTED,rollbackFor = Exception.class)@RequestMapping("/login2")public String login(String userName,String password) throws IOException {Integer result = userInfoService.insert(userName,password);if(result<=0){return  "添加失败";}else {Integer i = 10/0;return "添加成功";}}
}

运行程序,可以看到,当程序出现异常过后,事务就会自动回滚,但是当不存在 Integer i = 10/0;这一句的时候,数据库就会正常新增数据.

@Transactional 作用

可以用来修饰方法或类:
• 修饰方法时: 只有修饰public 方法时才生效(修饰其他方法时不会报错, 也不生效)[推荐]
• 修饰类时: 对 @Transactional 修饰的类中所有的 public 方法都生效.
方法/类被 @Transactional 注解修饰时, 在目标方法执行开始之前, 会自动开启事务, 方法执行结束之后, 自动提交事务.
如果在方法执行过程中, 出现异常, 且异常未被捕获, 就进行事务回滚操作.
如果异常被程序捕获, 方法就被认为是成功执行, 依然会提交事务.

对上述代码进行修改过后,

@RestController
public class UserInfoController2 {@Autowiredprivate UserInfoService userInfoService;@Transactional( isolation = READ_COMMITTED,rollbackFor = Exception.class)@RequestMapping("/login2")public String login(String userName,String password) throws IOException {Integer result = userInfoService.insert(userName,password);if(result<=0){return  "添加失败";}else {try {Integer integer = 10/0;}catch (Exception e){e.printStackTrace();}return "添加成功";}}
}

执行程序,可以看到,程序虽然报错,但是事务依旧提交成功了,数据库的数据已经成功新增了,如果在捕获了异常的情况下,想要将事务进行回滚,有以下两种方式

抛出异常

@RestController
public class UserInfoController2 {@Autowiredprivate UserInfoService userInfoService;@Transactional@RequestMapping("/login2")public String login(String userName,String password){Integer result = userInfoService.insert(userName,password);if(result<=0){return  "添加失败";}else {try {Integer integer = 10/0;}catch (Exception e){throw e;}return "添加成功";}}
}

手动回滚

@RestController
public class UserInfoController2 {@Autowiredprivate UserInfoService userInfoService;@Transactional@RequestMapping("/login2")public String login(String userName,String password){Integer result = userInfoService.insert(userName,password);if(result<=0){return  "添加失败";}else {try {Integer integer = 10/0;}catch (Exception e){TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}return "添加成功";}}
}

@Transactional 详解

rollbackFor

: 异常回滚属性. 指定能够触发事务回滚的异常类型. 可以指定多个异常类型

可以看到,以上两种方式,都可以在捕获异常的情况下进行事务的回滚,但是有特殊情况,@RestController默认只在遇到运行时异常和Error时抛出异常才会回滚, 非运行时异常不回滚. 即Exception的子类中, 除了RuntimeException及其子类.
在这里插入图片描述
这里我们假设抛出一个IOException

@RestController
public class UserInfoController3 {@Autowiredprivate UserInfoService userInfoService;@Transactional@RequestMapping("/login2")public String login(String userName,String password) throws IOException {Integer result = userInfoService.insert(userName,password);if(result<=0){return  "添加失败";}else {if (true){throw new IOException();}return "添加成功";}}
}

结果显示,虽然出现了异常,但事务仍旧提交了
如果我们需要所有异常都回滚, 需要来配置 @Transactional 注解当中的 rollbackFor 属性, 通
过 rollbackFor 这个属性指定出现何种异常类型时事务进行回滚

@RestController
public class UserInfoController3 {@Autowiredprivate UserInfoService userInfoService;@Transactional(rollbackFor = {Exception.class,Error.class})@RequestMapping("/login2")public String login(String userName,String password) throws IOException {Integer result = userInfoService.insert(userName,password);if(result<=0){return  "添加失败";}else {if (true){throw new IOException();}return "添加成功";}}
}

结果显示,事务得到了回滚,数据库中并未添加数据

事务隔离级别

SQL 标准定义了四种隔离级别, MySQL 全都⽀持. 这四种隔离级别分别是:

  1. 读未提交(READ UNCOMMITTED): 读未提交, 也叫未提交读. 该隔离级别的事务可以看到其他事务中未提交的数据.因为其他事务未提交的数据可能会发⽣回滚, 但是该隔离级别却可以读到, 我们把该级别读到的数据称之为脏数据, 这个问题称之为脏读
  2. 读提交(READ COMMITTED): 读已提交, 也叫提交读. 该隔离级别的事务能读取到已经提交事务的数据,该隔离级别不会有脏读的问题.但由于在事务的执⾏中可以读取到其他事务提交的结果, 所以在不同时间的相同 SQL 查询可能会得到不同的结果, 这种现象叫做不可重复读
  3. 可重复读(REPEATABLE READ): 事务不会读到其他事务对已有数据的修改, 即使其他事务已提交. 也就可以确保同⼀事务多次查询的结果⼀致, 但是其他事务新插⼊的数据, 是可以感知到的. 这也就引发了幻读问题. 可重复读, 是 MySQL 的默认事务隔离级别.
    ⽐如此级别的事务正在执⾏时, 另⼀个事务成功的插⼊了某条数据, 但因为它每次查询的结果都是⼀样的, 所以会导致查询不到这条数据, ⾃⼰重复插⼊时⼜失败(因为唯⼀约束的原因). 明明在事务中查询不到这条信息,但⾃⼰就是插⼊不进去, 这个现象叫幻读.
  4. 串⾏化(SERIALIZABLE): 序列化, 事务最⾼隔离级别. 它会强制事务排序, 使之不会发⽣冲突, 从⽽解决了脏读, 不可重复读和幻读问题, 但因为执⾏效率低, 所以真正使⽤的场景并不多
    在数据库中通过以下 SQL 查询全局事务隔离级别和当前连接的事务隔离级别:
select @@global.tx_isolation,@@tx_isolation;

Spring 中事务隔离级别

Spring 中事务隔离级别有5 种:
4. Isolation.DEFAULT : 以连接的数据库的事务隔离级别为主.
5. Isolation.READ_UNCOMMITTED : 读未提交, 对应SQL标准中 READ UNCOMMITTED
6. Isolation.READ_COMMITTED : 读已提交,对应SQL标准中 READ COMMITTED
7. Isolation.REPEATABLE_READ : 可重复读, 对应SQL标准中 REPEATABLE READ
8. Isolation.SERIALIZABLE : 串行化, 对应SQL标准中 SERIALIZABLE

通过以下代码进行实现
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/670703.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Angular 基础] - 指令(directives)

[Angular 基础] - 指令(directives) 这里假设已经知道如何创建 Angular 组件以及数据绑定&#xff0c;不然可以参考前两篇笔记&#xff1a; [Angular 基础] - Angular 渲染过程 & 组件的创建 [Angular 基础] - 数据绑定(databinding) 就像中文翻译一样&#xff0c;dire…

【已解决】pt文件转onnx后再转rknn时得到推理图片出现大量锚框变花屏

前言 环境介绍&#xff1a; 1.编译环境 Ubuntu 18.04.5 LTS 2.RKNN版本 py3.8-rknn2-1.4.0 3.单板 迅为itop-3568开发板 一、现象 采用yolov5训练并将pt转换为onnx&#xff0c;再将onnx采用py3.8-rknn2-1.4.0推理转换为rknn&#xff0c;rknn模型能正常转换&#xff0c;…

养好花草鱼鸟,也能旺家

不少朋友家里既养了鱼鸟&#xff0c;也养了花草&#xff0c;平时逗逗鸟喂喂鱼再赏赏花&#xff0c;真是非常惬意的生活&#xff0c;而用养鱼的水养植物&#xff0c;花草植物会长得格外茂盛。根据这一原理&#xff0c;很多人喜欢在养一些水培花草的时候&#xff0c;顺便养几尾小…

基于SpringBoot+Vue的外卖点餐管理系统

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 二、开发技术与环…

第三篇:SQL数据模型、通用语法和语法分类

一&#xff0c;SQL数据模型 &#xff08;一&#xff09;关系型数据库&#xff08;RDBMS&#xff09; 1.概念 &#xff08;百度百科&#xff09;指采用了关系模型来组织数据的数据库&#xff0c;其以行和列的形式存储数据&#xff0c;以便于用户理解&#xff0c;关系型数据库这…

【蓝桥杯选拔赛真题64】python数字塔 第十五届青少年组蓝桥杯python 选拔赛比赛真题解析

python数字塔 第十五届蓝桥杯青少年组python比赛选拔赛真题 一、题目要求 (注:input()输入函数的括号中不允许添加任何信息) 提示信息: 数字塔是由 N 行数堆积而成,最顶层只有一个数,次顶层两个数,以此类推。相邻层之间的数用线连接,下一层的每个数与它上一层左上…

网络安全大赛

网络安全大赛 网络安全大赛的类型有很多&#xff0c;比赛类型也参差不齐&#xff0c;这里以国内的CTF网络安全大赛里面著名的的XCTF和强国杯来介绍&#xff0c;国外的话用DenCon CTF和Pwn2Own来举例 CTF CTF起源于1996年DEFCON全球黑客大会&#xff0c;以代替之前黑客们通过互相…

EasyX图形库学习(三、用easyX控制图形界面中的小球、图片-加载、输出)

目录 小球视频 图像输出函数 loadimage用于从文件中读取图片 putimage在当前设备上绘制指定图像。 initgraph 函数 图片输出 代码详解&#xff1a; 1. 初始化图形界面 2. 设置背景颜色并清除屏幕 3. 加载并显示图片 4. 等待用户输入并退出程序 图形界面中的小球 1…

自动化诊断测试之CANoe.DIVA入门

目录 0 前言 1 CANoe.DIVA基础 2 CANoe.DIVA TIPs 0 前言 写在前面&#xff1a;如对本文有任何疑问欢迎评论区讨论&#xff0c;希望和大家一起进步。同时HIL测试群欢迎大家加入如有需要也可私信我拉你。VT和DIVA都可以做UDS的自动化测试&#xff0c;但相对VT来说使用DIVA生成…

Redis学习及总结

Redis 快速入门 Redis属于非关系型数据库 SQL应用场景 数据结构固定相关业务对数据安全性一致性要求高 NoSQL应用场景 数据结构不固定对一致性&#xff0c;安全性要求不高性能要求高 &#x1f3af;需要使用Xftp 传输压缩包到虚拟机上 安装好Redis后&#xff0c; 执行命令…

UE5 PAK包热加载

参考知乎UE5 Pak学习与应用&#xff08;一&#xff09;运行时导入模型 - 知乎 使用的版本为UE5.1 使用插件为HorPatcher和EasyFile Dialog HotPatcher:UE资源热更打包工具HotPatcher | 循迹研究室 ,Github地址为:GitHub - hxhb/HotPatcher: Unreal Engine hot update manage …

最小生成树超详细介绍

目录 一.最小生成树的介绍 1.最小生成树的简介 2.最小生成树的应用 3.最小生成树的得出方法 二.Kruskal算法 1.基本思想&#xff1a; 2.步骤&#xff1a; 3.实现细节&#xff1a; 4.样例分析&#xff1a; 5.Kruskal算法代码实现&#xff1a; 三.Prim算法 1.基本思想…

【多模态大模型】视觉大模型SAM:如何使模型能够处理任意图像的分割任务?

SAM&#xff1a;如何使模型能够处理任意图像的分割任务&#xff1f; 核心思想起始问题: 如何使模型能够处理任意图像的分割任务&#xff1f;5why分析5so分析 总结子问题1: 如何编码输入图像以适应分割任务&#xff1f;子问题2: 如何处理各种形式的分割提示&#xff1f;子问题3:…

【数据结构和算法】--- 基于c语言排序算法的实现(1)

目录 一、排序的概念及其应用1.1排序的概念1.2 排序的应用1.3 常见的排序算法 二、插入排序2.1直接插入排序2.2 希尔排序2.2.1 预排序2.2.2 缩小gap2.2.3 小结 三、选择排序3.1 直接选择排序3.2 堆排序 一、排序的概念及其应用 1.1排序的概念 排序&#xff1a; 所谓排序&…

RTE2023第九届实时互联网大会:揭秘未来互联网趋势,PPT分享引领行业新思考

随着互联网的不断发展&#xff0c;实时互动技术正逐渐成为新时代的核心驱动力。 在这样的背景下&#xff0c;RTE2023第九届实时互联网大会如期而至&#xff0c;为业界人士提供了一个探讨实时互联网技术、交流创新理念的绝佳平台。 本文将从大会内容、PPT分享价值等方面&#…

ShardingSphere 5.x 系列【6】YAML 配置介绍

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列ShardingSphere 版本 5.4.0 源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo 文章目录 1. 前言2. YamlConfiguration3. 常用配置项3.1 JDBC 驱动3.2 数据源3.3 规则…

mysq开启慢查询日志,对慢查询进行优化

1.创建实验的环境 创建对应的数据库&#xff0c;然后写脚本向数据库中写入400万条的数据 //创建实验用的数据库 CREATE DATABASE jsschool;//使用当前数据库 USE jsschool;//创建学生表 CREATE TABLE student (sno VARCHAR(20) PRIMARY KEY COMMENT 学生编号,sname VARCHAR(20…

加固平板电脑丨三防智能平板丨工业加固平板丨智能城市管理

随着智能城市的不断发展&#xff0c;人们对于城市管理的要求也在不断提高&#xff0c;这就需要高效、智能的城市管理平台来实现。而三防平板就是一款可以满足这一需求的智能设备。 三防平板是一种集防水、防尘、防摔于一体的智能平板电脑&#xff0c;它可以在复杂的环境下稳定运…

python介绍,安装Cpython解释器,IDE工具pycharm的使用

python介绍 官方的Python解释器本质是基于C语言开发的一个软件&#xff0c;该软件的功能就是读取以py.结尾的文件内容&#xff0c;然后按照Guido定义好的语法和规则去翻译并执行相应的代码。这种C实现的解释器被称为Cpython。 python解释器的种类&#xff1a;Jython IPyth…

记录下ibus-libpinyin输入法的重新安装

目前的版本为&#xff1a; 首先把现在的ibus-libpinyin卸了 sudo apt-get --purge remove ibus-libpinyin sudo apt-get autoremove 安装教程请参考 Installation libpinyin/ibus-libpinyin Wiki GitHub yilai sudo apt install pkg-config sudo apt-get install lib…