Spring 声明式事务 @Transactional

目录

一、添加依赖

二、@Transactional 作用

三、@Transactional详解

3.1 rollbackFor

3.2 事务隔离级别

3.3 Spring 事务传播机制


Spring 声明式事务 @Transactional的使用很简单,只需要添加依赖,在需要的方法或者类上添加 @Transactional注解即可。

一、添加依赖

<dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId>
</dependency>
在需要事务的方法上添加 @Transactional 注解就可以实现了,无需手动开启事务和提交事务,进入方法时自动开启事务,方法执行完会自动提交事务,如果中途发生了没有处理的异常会自动回滚事务。
代码示例:
@RequestMapping("/trans")
@RestController
public class TransactionalController {@Autowiredprivate UserService userService;@Transactional@RequestMapping("/registry")public String registry(String name,String password){//用户注册userService.registryUser(name,password);return "注册成功";}
}

假设代码有异常:

@Slf4j
@RequestMapping("/trans")
@RestController
public class TransactionalController {@Autowiredprivate UserService userService;@Transactional@RequestMapping("/registry")public String registry(String name,String password){//⽤户注册userService.registryUser(name,password);log.info("用户数据插⼊成功");//强制程序抛出异常int a = 10/0;return "注册成功";}
}
启动项目发现虽然日志显示数据插入成功,但数据库却没有新增数据,事务进行了回滚。

二、@Transactional 作用

@Transactional 可以用来修饰方法或类:
  • 修饰方法时: 只有修饰public 方法时才生效(修饰其他方法时不会报错, 也不生效)[推荐]
  • 修饰类时: 对 @Transactional 修饰的类中所有的 public 方法都生效。
方法/类被 @Transactional 注解修饰时,在目标方法执行开始之前,会自动开启事务,方法执行结束之后,自动提交事务。
如果在方法执行过程中,出现异常,且异常未被捕获,就进行事务回滚操作。
如果异常被程序捕获,方法就被认为是成功执行,依然会提交事务。
举例:(对异常进行捕获)
@Transactional
@RequestMapping("/registry")
public String registry(String name,String password){//⽤⼾注册userService.registryUser(name,password);log.info("⽤⼾数据插⼊成功");//对异常进⾏捕获try {//强制程序抛出异常int a = 10/0;}catch (Exception e){e.printStackTrace();}return "注册成功";
}
运行程序,发现虽然程序出错了,但是由于异常被捕获,所以事务依然得到了提交。
如果需要事务进行回滚,有以下两种方式:
  • 重新抛出异常
@Transactional
@RequestMapping("/registry")
public String registry(String name,String password){
//⽤户注册
userService.registryUser(name,password);
log.info("⽤⼾数据插⼊成功");//对异常进⾏捕获try {//强制程序抛出异常int a = 10/0;}catch (Exception e){//将异常重新抛出去throw e;}return "注册成功";
}
  • 手动回滚事务
使用 TransactionAspectSupport.currentTransactionStatus() 得到当前的事务,并使用用 setRollbackOnly 设置 setRollbackOnly
@Transactional
@RequestMapping("/registry")
public String registry(String name,String password){
//⽤户注册
userService.registryUser(name,password);
log.info("⽤户数据插⼊成功");
//对异常进行捕获
try {
//强制程序抛出异常
int a = 10/0;
}catch (Exception e){
// 手动回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return "注册成功";
}

三、@Transactional详解

@Transactional注解有三个常见的属性:

  • rollbackFor: 异常回滚属性。指定能够触发事务回滚的异常类型,可以指定多个异常类型。
  • isolation: 事务的隔离级别。默认值为 Isolation.DEFAULT
  • propagation: 事务的传播机制。默认值为 Propagation.REQUIRED

3.1 rollbackFor

@Transactional 默认只在遇到运行时异常和Error时才会回滚,非运行时异常不回滚。即
Exception的子类中,除了RuntimeException及其子类。
如果需要所有异常都回滚,需要来配置 @Transactional 注解当中的 rollbackFor 属性,通过rollbackFor 这个属性指定出现何种异常类型时事务进行回滚。
@Transactional(rollbackFor = Exception.class)
@RequestMapping("/r2")
public String r2(String name,String password) throws IOException {//⽤户注册userService.registryUser(name,password);log.info("⽤户数据插⼊成功");if (true){throw new IOException();}return "r2";
}
运行程序会发现虽然程序抛出了异常,但是事务依然进行了提交。

3.2 事务隔离级别

事务隔离级别解决的是多个事务同时调用一个数据库的问题:

Spring 中事务隔离级别有5 种:
  1. Isolation.DEFAULT : 以连接的数据库的事务隔离级别为主;
  2. Isolation.READ_UNCOMMITTED : 读未提交,对应SQL标准中 READ UNCOMMITTED;
  3. Isolation.READ_COMMITTED : 读已提交,对应SQL标准中 READ COMMITTED;
  4. Isolation.REPEATABLE_READ : 可重复读,对应SQL标准中 REPEATABLE READ;
  5. Isolation.SERIALIZABLE : 串行化,对应SQL标准中 SERIALIZABLE。
public enum Isolation {DEFAULT(-1),READ_UNCOMMITTED(1),READ_COMMITTED(2),REPEATABLE_READ(4),SERIALIZABLE(8);private final int value;private Isolation(int value) {this.value = value;}public int value() {return this.value;}
}
Spring 中事务隔离级别可以通过 @Transactional 中的 isolation 属性进行设置:
@Transactional(isolation = Isolation.READ_COMMITTED)
@RequestMapping("/r3")
public String r3(String name,String password) throws IOException {//... return "r3";
}

3.3 Spring 事务传播机制

事务传播机制就是: 多个事务方法存在调用关系时,事务是如何在这些方法间进行传播的。

事务传播机制解决的是一个事务在多个节点(方法)中传递的问题:

@Transactional 注解支持事务传播机制的设置, 通过 propagation 属性来指定传播行为。
Spring 事务传播机制有以下 7 种:
  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。
public enum Propagation {REQUIRED(0),SUPPORTS(1),MANDATORY(2),REQUIRES_NEW(3),NOT_SUPPORTED(4),NEVER(5),NESTED(6);private final int value;private Propagation(int value) {this.value = value;}public int value() {return this.value;}
}
NESTED 和 REQUIRED 区别:
  • 整个事务如果全部执行成功,二者的结果是一样的。
  • 如果事务一部分执行成功,REQUIRED加入事务会导致整个事务全部回滚。NESTED嵌套事务可以实现局部回滚,不会影响上一个方法中执行的结果。
一个非常形象的比喻:
比如一对新人要结婚了, 关于是否需要房子:
1. Propagation.REQUIRED : 需要有房子。 如果你有房,我们就一起住,如果你没房,我们就一起买房。(如果当前存在事务,则加入该事务。如果当前没有事务,则创建一个新的事务)
2. Propagation.SUPPORTS : 可以有房子。如果你有房, 那就一起住。如果没房,那就租房。 (如果当前存在事务,则加入该事务。如果当前没有事务,则以非事务的方式继续运行)
3. Propagation.MANDATORY : 必须有房子。要求必须有房,如果没房就不结婚。(如果当前存在事务, 则加⼊该事务。如果当前没有事务,则抛出异常)
4. Propagation.REQUIRES_NEW : 必须买新房。不管你有没有房,必须要两个人一起买房。即使
有房也不住。(创建一个新的事务. 如果当前存在事务, 则把当前事务挂起)
5. Propagation.NOT_SUPPORTED : 不需要房。不管你有没有房, 我都不住,必须租房。(以非事务方式运行,如果当前存在事务,则把当前事务挂起)
6. Propagation.NEVER : 不能有房子。(以非事务方式运行,如果当前存在事务,则抛出异常)
7. Propagation.NESTED : 如果你没房,就一起买房。如果你有房,我们就以房子为根据地。做点生意。(如果如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行。如果当前没有事务,则该取值等价于 PROPAGATION_REQUIRED )

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

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

相关文章

AMBA-CHI协议详解(六)

AMBA-CHI协议详解&#xff08;一&#xff09; AMBA-CHI协议详解&#xff08;二&#xff09; AMBA-CHI协议详解&#xff08;三&#xff09; AMBA-CHI协议详解&#xff08;四&#xff09; AMBA-CHI协议详解&#xff08;五&#xff09; AMBA-CHI协议详解&#xff08;六&#xff09…

硬件面试经典 100 题(71~90 题)

71、请问下图电路的作用是什么&#xff1f; 该电路实现 IIC 信号的电平转换&#xff08;3.3V 和 5V 电平转换&#xff09;&#xff0c;并且是双向通信的。 上下两路是一样的&#xff0c;只分析 SDA 一路&#xff1a; 1&#xff09; 从左到右通信&#xff08;SDA2 为输入状态&…

Golang | Leetcode Golang题解之第349题两个数组的交集

题目&#xff1a; 题解&#xff1a; func intersection(nums1 []int, nums2 []int) (res []int) {sort.Ints(nums1)sort.Ints(nums2)for i, j : 0, 0; i < len(nums1) && j < len(nums2); {x, y : nums1[i], nums2[j]if x y {if res nil || x > res[len(re…

Python基础和变量使用

1. 基础了解 1.1 运行方式 Python有多种运行方式&#xff0c;以下是几种常见的执行Python代码的方法&#xff1a; 交互式解释器&#xff1a; 打开终端或命令提示符&#xff0c;输入python或python3&#xff08;取决于你的系统配置&#xff09;&#xff0c;即可进入Python交互…

设计模式---构建者模式(Builder Pattern)

构建者模式&#xff08;Builder Pattern&#xff09; 是一种创建型设计模式&#xff0c;旨在将复杂对象的构建过程与其表示分离。它允许使用相同的构建过程创建不同的表示。该模式通常用于构建复杂对象&#xff0c;这些对象由多个部分组成或具有多个可选属性。 构建者模式的核…

Python做统计图之美

Python数据分析可视化 案例效果图 import pandas as pd import matplotlib.pyplot as plt import matplotlib# 数据 data {"房型": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],"住宅类型": ["普通宅", "普通宅", "普通宅", &q…

ffmpeg开发者视频剪辑器

5G 时代的来临&#xff0c;加速了视频类作品的创作&#xff0c;由于现在的流量越来越便宜&#xff0c;网速越来越快&#xff0c;特别是流量无限用套餐&#xff0c;大家更愿意去看视频作品&#xff0c;特别是抖音的兴起&#xff0c;更是加速了小视频的流量。不会剪辑的我们该如何…

内网安全:跨域攻击

目录 获取域信息 利用域信任密钥获取目标域 利用krbtgt哈希值获取目标域 内网中的域林&#xff1a; 很多大型企业都拥有自己的内网&#xff0c;一般通过域林进行共享资源。根据不同职能区分的部门&#xff0c;从逻辑上以 主域和子域进行区分&#xff0c;以方便统一管理。在…

选择排序(直接选择排序与堆排序的比较)

选择排序 选择排序时间复杂度 1. 直接选择排序思考⾮常好理解&#xff0c;但是效率不是很好。实际中很少使用&#xff0c;思路是先进行遍历找到元最小的元素&#xff0c;然后与第一个进行交换 2. 时间复杂度&#xff1a;O&#xff08;&#xff09; 3. 空间复杂度&#…

openharmony 南向开发基础:ohos自定义子系统,自定义部件,调用hilog部件,hilog日志封装傻瓜式教程

openharmony 南向开发基础:ohos自定义子系统,自定义部件,调用hilog部件,hilog日志封装 自定义单部件 关于开源鸿蒙的南向教程不多,很多都是从官方文档上抄的的例子,官网的例子不是很适合入门,写的很粗糙,不适合傻瓜阅读,毕竟对于刚入行鸿蒙的新手而言,gn语法就是第一劝退魔咒…

vue 路由用法 router-view

通过router-view 点击子路由显示子路由关于我们的内容&#xff0c;点击关于信息显示关于信息内容。

map/set和unordered_map/unordered_set的区别及使用情况

map/set和unordered_map/unordered_set的区别 容器底层数据结构是否有序实现版本复杂度迭代器map/set红黑树有序C98O(logN&#xff09;双向迭代器unordered_map/unordered_set哈希表/散列表无序C11O(1)单向迭代器 unordered_set无序的&#xff08;VS下&#xff09; void uno…

【机器学习】探索数据矿藏:Python中的AI大模型与数据挖掘创新实践

&#x1f496; 前言&#xff1a;探索数据矿藏1. &#x1f4ca;数据获取与预处理&#xff1a;AI大模型的燃料1.1 &#x1f310;数据获取&#xff1a;多样性与规模并重1.2 &#x1f9f9;数据清洗与处理&#xff1a;提升数据质量1.3 &#x1f50d;特征工程&#xff1a;挖掘数据的深…

蓝牙音视频远程控制协议(AVRCP) command跟response介绍

零.声明 本专栏文章我们会以连载的方式持续更新&#xff0c;本专栏计划更新内容如下&#xff1a; 第一篇:蓝牙综合介绍 &#xff0c;主要介绍蓝牙的一些概念&#xff0c;产生背景&#xff0c;发展轨迹&#xff0c;市面蓝牙介绍&#xff0c;以及蓝牙开发板介绍。 第二篇:Trans…

[Qt][QSS][下]详细讲解

目录 1.样式属性0.前言1.盒模型(Box Model) 2.常用控件样式属性1.按钮2.复选框3.单选框4.输入框5.列表6.菜单栏7.注意 1.样式属性 0.前言 QSS中的样式属性⾮常多&#xff0c;不需要都记住&#xff0c;核⼼原则是⽤到了就去查 ⼤部分的属性和CSS是⾮常相似的 QSS中有些属性&am…

稚晖君发布5款全能人形机器人,开源创新,全能应用

8月18日&#xff0c;智元机器人举行“智元远征 商用启航” 2024年度新品发布会&#xff0c;智元联合创始人彭志辉主持并发布了“远征”与“灵犀”两大系列共五款商用人形机器人新品——远征A2、远征A2-W、远征A2-Max、灵犀X1及灵犀X1-W&#xff0c;并展示了在机器人动力、感知、…

爱心商城系统pf

TOC springboot424爱心商城系统pf 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现&#xff0c;改变了几千年以来人们的生活&#xff0c;不仅仅是生活物资的丰富&#xff0c;还有精神层次的丰富。在互联网诞生之前&#xff0c;地域位置往往是人们思想上不可跨域的鸿沟&…

在亚马逊云科技上安全、合规地创建AI大模型训练基础设施并开发AI应用服务

项目简介&#xff1a; 小李哥将继续每天介绍一个基于亚马逊云科技AWS云计算平台的全球前沿AI技术解决方案&#xff0c;帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS AI最佳实践&#xff0c;并应用到自己的日常工作里。 本次介绍的是如何在亚马逊云科技利用Servi…

Mac电脑虚拟机安装win11教程

Mac分享吧 文章目录 效果一、准备工作二、安装步骤方法1&#xff1a;使用虚拟机自带的win11系统&#xff0c;选中系统软件--继续--安装&#xff0c;即可完成win11安装方法2&#xff1a;通过下载好的镜像安装Windows11系统。选择镜像文件位置&#xff0c;安装&#xff0c;配置1…

前后端项目交互异步请求JSON数据类型后端标准响应数据格式

java同步请求 当网页与后端交互时,前端不能再进行其他操作 服务器响应回来的内容,会把整个浏览器中的内容覆盖 这种请求方式在前后端交互时不太友好 现在的前后端交互请求都使用异步请求 异步请求(不同步) 通过在前端中使用js中提供的XMLHttpRequest对象实现发送异步请求…