03. Spring 事务管理

文章目录

  • 1. Spring 事务管理简介
  • 2. @Transactional 注解属性信息
  • 3. @Transactional 简单使用
  • 4. @Transactional 使用注意事项
    • 4.1 正确指定事务回滚的异常类型
      • 4.1.1 Java 异常继承体系
    • 4.2 `@Transactional` 注解应用在 `public` 方法或类上才有效
    • 4.3 正确设置 `@Transactional` 的 `propagation` 属性。
      • 4.3.1 事务的传播行为
      • 4.3.2 `TransactionDefinition` 和 `Propagation`
  • 5. Spring 事务失效的场景
    • 5.1 @Transactional 注解使用在非 public 方法上,导致事务失效
    • 5.2 propagation 参数设置错误,导致事务失效
    • 5.3 rollbackFor 参数设置错误,导致事务失效
    • 5.4 在同一个类中,方法之间的相互调用导致事务失效
    • 5.5 异常被捕获导致事务失效
    • 5.6 数据库引擎不支持事务

1. Spring 事务管理简介

事务管理是应用系统开发中必不可少的一部分,Spring 为事务管理提供了丰富的功能。Spring 的事务管理分为编程式和声明式两种方式。声明式事务管理可以使业务代码逻辑不受污染,将业务逻辑和事务处理解耦。声明式事务也有两种方式:一种是在配置文件(xml)中做相关的事务规则声明,一种是基于注解 @Transactional 的方式

事务是数据库的概念,Spring 本身是没有事务的,Spring 的事务是借助 AOP,通过动态代理的方式实现。
在我们要操作数据库的时候,实际是 Spring 通过动态代理进行功能拓展,在我们的代码操作数据库之前通过数据库客户端打开数据库事务,如果代码执行完毕没有异常信息或者是没有 Spring 要捕获的异常信息时,再通过数据库客户端提交事务;如果有异常信息或者是有 Spring 要捕获的异常信息,再通过数据库客户端程序回滚事务,从而控制数据库事务。

Spring 基于注解使用事务主要有两步:

  • 在主配置类上声明 @EnableTransactionManagement 注解,表示开启声明式事务;
  • 在访问数据库的方法上添加 @Transactional 注解。

@Transactional 注解也可以用在类上,表示该类的所有公共方法都配置相同的事务属性。如果类和方法都配置了 @Transactional,应用程序会用方法级别的事务属性来管理事务。

2. @Transactional 注解属性信息

属性名说明
name当配置文件中有多个 TransactionManager时,可以用该属性指定选择哪个事务管理器
propagation事务的传播行为,默认值:REQUIRED
isolation事务的隔离度,默认值:DEFAULT
timeout事务的超时时间,默认值 -1。如果超过该时间但事务未完成,则回滚该事务
readOnly指定事务为只读事务,默认值 false。指定当前事务为只读事务后,当前事务不能进行写操作,否则报错
rollbackFor指定能够触发事务回滚的异常类型,如果有多个异常类型要指定,用逗号分隔
noRollbackFor抛出该参数指定的异常类型,不回滚事务

3. @Transactional 简单使用

如下有一个保存数据的方法,加上 @Transactional 注解,运行时抛出运行时异常之后,事务会自动回滚,数据不会插入数据库。

    @Override@Transactionalpublic boolean save() {boolean res = stateRepository.save();if(true) {throw new RuntimeException();}return res;}
  • 如果去掉 @Transactional 注解,save() 就是一个普通的没有事务的方法,执行时还是会抛出异常,但是会插入数据。
  • 如果加上 @Transactional 注解,但是在方法内使用 try-catch 捕获异常,则事务不会回滚,数据会插入成功。
        @Override@Transactionalpublic boolean save() {boolean res = stateRepository.save();try {if(true) {throw new RuntimeException();}}catch (Exception e){e.printStackTrace();}return res;}
    

4. @Transactional 使用注意事项

4.1 正确指定事务回滚的异常类型

默认情况下,@Transactional 会在运行时异常及其子类异常时回滚事务,其他类型的异常 Spring 不会帮我们回滚事务。如果要在指定类型的异常时回滚事务,需要使用 rollbackFor 指定异常类型,如 @Transacrional(rollbackFor = Exception.class)

4.1.1 Java 异常继承体系

在这里插入图片描述
最顶层的异常类型是可抛出异常 Throwable,有 ErrorException 两个子类。

  • Error 表示严重的错误(如 OOM);
  • Exception 分为 运行时异常(RuntimeException)和非运行时异常;
  • 非运行时异常是检查异常(checked exceptions),编译阶段就能检查出来,编码时需要 try-catch 或抛出异常。
  • Error 和运行时异常是非检查异常(unchecked exceptions),编译阶段不会检查。

4.2 @Transactional 注解应用在 public 方法或类上才有效

只有 @Transactional 注解应用到 public 方法,才能进行事务管理。

4.3 正确设置 @Transactionalpropagation 属性。

propagation 属性用于指定事务的传播行为,当 propagation 参数指定为 SUPPORTSNOT_SUPPORTEDNEVER 时,事务将不会发生回滚。

4.3.1 事务的传播行为

事务的传播行为是指,多个事务方法相互调用时,事务如何在这些方法之间传播。

Spring 支持一下 7 种事务传播行为,定义在枚举类 Propagation

传播类型说明
REQUIRED(默认值)支持当前事务,如果有就加入当前事务中。如果当前方法没有事务,则新建一个事务
SUPPORTS支持当前事务,如果有就加入当前事务中。如果当前方法没有事务,则以非事务方式执行
MANDATORY支持当前事务,如果有就加入当前事务中。如果当前方法没有事务,就抛出异常
REQUIRES_NEW如果当前存在事务,就把当前事务挂起,然后新建一个事务;如果当前方法不存在事务,就新建一个事务
NOT_SUPPORTED以非事务方式执行,如果当前方法存在事务就挂起当前事务,执行完后恢复事务
NEVER以非事务方式执行,如果当前方法存在事务,则抛出异常
NESTED如果当前存在事务,则嵌套在当前事务中。如果当前没有事务,则新建一个事务自己执行。(嵌套事务使用保存点作为回滚点,内部事务回滚不影响外部事务的提交,但是外部事务的回滚会把内部事务一起回滚。)

4.3.2 TransactionDefinitionPropagation

TransactionDefinition 和 Propagation 是 Spring 框架中两个不同的概念,它们在事务管理中起着不同的作用。

  • TransactionDefinition 是一个接口,它定义了事务的基本属性,如隔离级别、传播行为、超时时间等。它允许您为事务设置各种属性,并将这些属性应用于事务管理器。
  • Propagation是一个枚举,它定义了事务的传播行为。事务传播行为确定了当一个事务方法被另一个事务方法调用时会发生什么。它控制了事务如何与现有事务相关联,以及是否创建新的事务。
  • 总之,TransactionDefinition 是关于定义事务属性的,而 Propagation 是关于控制事务传播行为的。它们在 Spring 框架的事务管理中发挥着重要作用,使开发人员能够精细地控制事务的行为。

5. Spring 事务失效的场景

5.1 @Transactional 注解使用在非 public 方法上,导致事务失效

5.2 propagation 参数设置错误,导致事务失效

propagation 参数设置为 SUPPORTSNOT_SUPPORTEDNEVER 时,@Transactional 注解就不会产生效果。

5.3 rollbackFor 参数设置错误,导致事务失效

  • Spring 默认在方法抛出未检查异常或 Error 时回滚事务,其他异常类型不会回滚;
  • 如果要在方法抛出其他异常时也能回滚事务,需要 rollbackFor 参数指定异常类型。

5.4 在同一个类中,方法之间的相互调用导致事务失效

如下,在 StateService 中有两个保存方法:

	@Override@Transactionalpublic boolean save() {save2();boolean res = stateRepository.save();if(true) {throw new RuntimeException();}return res;}private boolean save2() {StateDAO stateDAO = new StateDAO();stateDAO.setWorkspaceKey("space1");return stateRepository.saveState(stateDAO);}

save() 方法首先调用了 save2() 方法,然后 save() 方法抛出异常,导致事务回滚,两条数据都不会插入数据库。

现在我们想实现:save() 方法抛异常不影响 save2() 方法插入数据。@Transactionalpropagation 参数可以设置事务的传播行为,我们可以尝试给 save2() 方法设置 propagation = REQUIRES_NEW 去实现。如下:

    @Override@Transactional(propagation = Propagation.REQUIRED)public boolean save() {save2();boolean res = stateRepository.save();if(true) {throw new RuntimeException();}return res;}@Transactional(propagation = Propagation.REQUIRES_NEW)private boolean save2() {StateDAO stateDAO = new StateDAO();stateDAO.setWorkspaceKey("space1");return stateRepository.saveState(stateDAO);}

但是,运行之后,发现 save2() 方法的数据也没有插入数据库。

原因:

在默认的代理模式下,只有目标方法由外部调用,才能被 Spring 的事务拦截器拦截。在同一个类的两个方法直接调用,不会被 Spring 的事务拦截器,也就是说 save2() 方法的 @Transactional 注解是失效的。

为解决该问题,可以新建一个 service 类,提供 save2() 方法。然后在 save() 方法中调用这个外部的 save2() 方法。

5.5 异常被捕获导致事务失效

事务通知只有捕获到了目标抛出的异常,才能进行回滚处理;如果目标自己处理掉异常,事务通知无法知悉。

如:

    @Override@Transactionalpublic boolean save() {boolean res = planBaselineStateRepository.save();try {if(true) {throw new RuntimeException();}}catch (Exception e){e.printStackTrace();}return res;}

5.6 数据库引擎不支持事务

  • InnoDB 引擎支持事务,是 MySQL 默认的引擎;
  • MyIsam 引擎不支持事务。

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

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

相关文章

西门子smart line触摸屏软件安装 WinCC Flexible Smart V4SP1 V3

提示:Wincc flexible smart软件为西门子Smart line系列触摸屏的专用组态软件,这款屏不能用博途来组态,只能用这个软件来组态。西门子Smart line系列触摸屏的常用型号为SMART 700 IE V3/V4,SMART 1000 IE V3/V4。 Wincc flexible …

类和对象(上)【有关类的全面学习】【this指针的学习】

类和对象(上) 1.面向过程和面向对象初步认识 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 C语言注重过程: C是基于面向对象的,关注的是对象&#xff0…

Spring - Spring Cache 缓存注解这样用,实在是太香了!

作者最近在开发公司项目时使用到 Redis 缓存,并在翻看前人代码时,看到了一种关于 Cacheable 注解的自定义缓存有效期的解决方案,感觉比较实用,因此作者自己拓展完善了一番后分享给各位。 Spring 缓存常规配置 Spring Cache 框架给…

IC解析之TPS1HB08-Q1

目录 1.主要参数2. 接口定义3. 工作原理分析高低边驱动的作用TPS1HB08-Q1架构TPS1HB08-Q1典型应用电路参数设置 4.总结 1.主要参数 2. 接口定义 其中,不同的IC版本在故障反馈引脚有所差异,A/B版本则为ILIM功能,F版本则为FLT功能,两…

javaEE—图书管理系统(基础代码版)

前言: 本篇博客是集合了javaEE所学的知识构建的一个基础框架,讲述着面向对象的过程是如何做到多对象交互协作完成框架的构建的。利用了数组,接口,类和对象,抽象类,Object类等知识来完成。 后续会加入数据…

力扣刷题--268. 丢失的数字【简单】

题目描述🍗 给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。 示例 1: 输入:nums [3,0,1] 输出:2 解释:n 3,因为有 3 个数字,所以…

PyTorch深度学习快速入门——P1-P13

环境配置 Anaconda,创建conda create -n pytorch python3.12,使用conda activate pytorch切换到环境。安装pytorch,conda install pytorch torchvision torchaudio pytorch-cuda11.8 -c pytorch -c nvidia,使用import torch&…

水滴式粉碎机:让破碎多样化

水滴式粉碎机以其新的粉碎技术和卓越的性能,引领着粉碎技术的新革命。它采用了高速旋转技术,通过转子对物料进行撞击和摩擦,实现了对物料的精细粉碎,制备出了高品质、高附加值的产品。 水滴式粉碎机在多个行业中都有着广泛的应用…

C++的红黑树

目录 基本概念 插入结点的颜色 判断性质是否破坏 调整方式 u为g的右孩子 u存在且为红 u存在且为黑 u不存在 结论 红黑树结点定义 代码实现 基本概念 1、红黑树是一种特殊的二叉搜索树,每个结点会增加一个存储位表示结点的颜色(红或黑&#x…

数据泄露防护:企业如何通过软件限制U盘使用

在数字化办公时代,数据安全已成为企业运营中的一个关键议题。U盘作为一种便携式的数据存储和传输工具,其使用在企业内部非常普遍。然而,U盘的不当使用也可能导致严重的数据泄露问题。本文将探讨企业如何通过软件解决方案,有效限制…

1小时从0开始搭建自己的直播平台(详细步骤)

本文讲述了如何从0开始,利用腾讯云的平台,快速搭建一个直播平台的过程。 文章目录 效果图详细步骤准备工作第一步:添加域名并检验cname配置1.先填加一个推流域名2. 点击完下一步,得到一个cname地址3. 将cname地址,配置…

QT 掩码 InputMask

字符规则 如IP输入框可以简单设置为 IP->setInputMask("000.000.000.000");就会有80%的相似度 另外设置掩码用 ui.edtIP->setInputMask(“这里面是字符格式”); ★消除已有的掩码用 ui.edtIP->setInputMask(" "); 而不是ui.…

关于VFX Graph的学习

关于VFX Graph的学习 转载自我的有道云笔记,目前内容不多,后续如果继续使用会更新。 前言 出于实习工作需要和毕设需要,我开始使用VFXGraph。 以前准备第一批作品集的时候,就简单地使用过,但是只是跟着教程一顿乱连…

【方法】ZIP压缩文件的密码如何设置和取消?

ZIP是一种常见的压缩文件格式,今天来分享一下,ZIP压缩文件如何设置密码保护,以及如何取消密码,不清楚的小伙伴一起来看看吧! 设置ZIP文件密码: 想要给ZIP压缩包设置密码,需要用到支持ZIP格式的…

记一次 .NET某企业数字化平台 崩溃分析

一:背景 1. 讲故事 前些天群里有一个朋友说他们软件会偶发崩溃,想分析看看是怎么回事,所幸的是自己会抓dump文件,有了dump就比较好分析了,接下来我们开始吧。 二:WinDbg 分析 1. 程序为什么会崩溃 win…

2024-BurpSuite快速配置Jython插件环境

文章目录 前言一、下载Jython二、配置Python environment 前言 很多插件需要python环境,Burpsuite本身是支持java的,Jython就是java和python的结合。 提示:以下是本篇文章正文内容,下面案例可供参考 一、下载Jython https://ww…

.NET调用阿里云人脸核身服务端 (ExecuteServerSideVerification)简易流程保姆级教学

需要注意的是,以下内容仅限基础调用 功能说明 该功能是输入核验人的姓名和身份证以及人脸照片,去阿里库里面匹配,3个信息是否一致,一致则验证通过,需要注意的是,人脸有遮挡,或者刘海&#xff0…

吴恩达2022机器学习专项课程C2W2:2.17 TensorFlow实现 2.18 训练细节

这里写目录标题 本周任务TensorFlow训练神经网络模型的简要过程训练模型的三个步骤1.自行训练逻辑回归模型2.TensorFlow训练神经网络模型 TensorFlow训练神经网络模型的代码含义1.定义模型2.指定损失函数和成本函数3.最小化成本函数 总结QuizQuiz1Quiz2 本周任务 神经网络如何…

汇聚荣科技有限公司怎么样?

在众多企业中,汇聚荣科技有限公司以其独特的发展模式和市场定位引起了人们的关注。对于这个问题,答案并非简单的好与坏,而需要从多个维度进行深入分析。 一、公司背景与发展历程汇聚荣科技有限公司成立于何年何地,由谁创立&#x…

40岁的戴尔在AI时代翻红了

戴尔公司股价创历史新高,市值达1138亿美元,涨幅110%。戴尔向AI押注多年,收购企业转型,成为数据基础设施厂商。AI服务器销售增长,分析师看好戴尔未来发展。 5月24日美股收盘,很多人可能不太关注的戴尔公司股…