记录一次Spring事务线上异常

news2024/11/25 16:24:18

Spring事务管理配置方式:

  • XML模糊匹配,绑定事务管理
  • 注解,可对每个需要进行事务处理的方法单独配置,只需 @Transactional,然后添加属性配置

为简便,本文使用注解方式。Spring初始化时,会通过扫描拦截对事务的方法进行增强。若目标方法存在事务,Spring就会创建一个Bean对应的代理(Proxy)对象,并进行相关的事务处理操作。

1 setup

1.1 数据库配置文件 jdbc.properties

1.2 JDBC配置类

从 jdbc.properties 加载相关配置项,并创建 JdbcTemplate、DataSource、TransactionManager 等相关Bean。

1.3 应用配置类

通过注解,配置了数据源、MyBatis Mapper 的扫描路径以及事务等。

2 unchecked 异常与事务回滚

用户管理功能,每位用户注册后,都往数据库里存入信息:

Mapper类:

数据库表Schema:

业务类 StudentService包括一个保存的方法 saveStudent。执行一下保存,一切正常。

测试该事务是否回滚:若发现用户名=JavaEdge,抛异常,触发事务回滚。

测试保存我这个用户:

执行结果打印出了这样的信息:

异常抛了,但观察到DB还是有条新记录。

那为何异常也抛了,却没有回滚?

3 源码解析

顺着 saveUser debug:

看到 CglibAopProxy,事务本质上也是一种特殊切面,在创建过程中,被 CglibAopProxy 代理。
事务处理拦截器是 TransactionInterceptor支撑整个事务功能的架构

TransactionInterceptor如何实现事务特性


执行代理类的目标方法时,触发invoke()。跳到异常处理。catch到异常时,调 completeTransactionAfterThrowing进一步处理。

TransactionAspectSupport#invokeWithinTransaction

completeTransactionAfterThrowing.rollbackOn()

事务回滚判断条件。条件满足时,即会触发事务回滚。

RuleBasedTransactionAttribute#rollbackOn()

RuleBasedTransactionAttribute自身的rollbackOn()

当在 @Transactional 配置 rollbackFor,该方法就会用捕获到的异常和 rollbackFor 中配置的异常比对:

  • 所捕获异常是 rollbackFor 配置异常,直接 rollback

案例中,没有加任何规则,所以找不到规则去处理(所以 winner == null),进而走到下一步。

DefaultTransactionAttribute 的 rollbackOn()

当发生如下 case:

  • 没有在 @Transactional 配置 rollback 属性
  • 或者,捕获到的异常和所配置异常类型不一

就调用父类rollbackOn():

只有异常类型为 RuntimeException 或 Error,才true
=》才触发 completeTransactionAfterThrowing#rollback
=》事务才回滚:

综上,Spring 处理事务时,若没有在 @Transactional 配置 rollback 属性,则只有捕获到 RuntimeException 或 Error 才会触发事务回滚。
而案例抛 Exception,又未指定回滚规则,所以未触发回滚。

4 修正

将所抛异常类型改成 RuntimeException:

这种修改方法不优雅,毕竟异常有时就是固定死不能修改。还有更好方案。

解析 RuleBasedTransactionAttribute#rollbackOn 的代码时提到过 rollbackFor 属性的处理规则。在 @Transactional 的 rollbackFor 加入要支持的异常类型(在这是 Exception)即可匹配上我们所抛异常。完善注解配置即可:

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

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

相关文章

C进阶:通讯录(动态版本 + 文件操作)附源码

本文主要讲解通讯录的代码; 需要拥有结构体,动态内存开辟,文件操作的知识; 目录 🐲一.通讯录思路 🕊️二.三个文件的建立 😼三.所需要使用的变量的创建(包含在头文件contact.h中&…

从0到1完成一个Vue后台管理项目(十三、信息列表页面实现:对话框新增、DateTimePicker 日期时间选择器)

往期 从0到1完成一个Vue后台管理项目(一、创建项目) 从0到1完成一个Vue后台管理项目(二、使用element-ui) 从0到1完成一个Vue后台管理项目(三、使用SCSS/LESS,安装图标库) 从0到1完成一个Vu…

JavaScript 事件流

文章目录JavaScript 事件流概述事件冒泡简介onclick() 事件冒泡addEventListener() 事件冒泡stopPropagation() 阻止事件冒泡事件捕获简介addEventListener() 事件捕获W3C标准事件流取消事件默认行为取消使用对象属性绑定的事件的默认行为取消使用addEventListener()绑定的事件…

社科院与杜兰大学金融管理硕士项目你有了解吗?每年招生一期错过申请太可惜了

社科院与杜兰大学金融管理硕士是个什么项目?社科院是所学校吗,怎么都没听说过。杜兰大学又是哪里的学校?前几天有位咨询的同学抛出这些疑问,着实让我不知如何给予回答。像社科院这么低调的院校太少了。社科院全称是中国社会科学院…

错题 5jxn 8253,neg指令,知CPU频率求经典总线周期,如何取一个字,字扩展指令CBW扩展要求,知道相对位移量求转移后指令偏移地址

1:8253工作于方式1时,输出负脉冲的宽度等于() A:计数初值N-1个CLK脉冲宽度 B:计数初值N1个CLK脉冲宽度C:计数初值N个CLK脉冲宽度 D:计数初值(2N-1)/2个CLK脉冲宽度 方式0和方式1 波形相同(计数过程中低,计数完高)&…

Pytorch 暂退法(Dropout)

在2014年,斯里瓦斯塔瓦等人 (Srivastava et al., 2014) 就如何将毕晓普的想法应用于网络的内部层提出了一个想法: 在训练过程中,他们建议在计算后续层之前向网络的每一层注入噪声。 因为当训练一个有多层的深层网络时,注入噪声只会…

八、Gtk4-GtkBuilder and UI file

1 New, Open and Save button 在上一节中,我们制作了一个非常简单的编辑器。它在程序开始时读取文件,在程序结束时将文件写出来。它可以工作,但不是很好。如果我们有“新建”、“打开”、“保存”和“关闭”按钮就更好了。本节介绍如何在窗口…

【年度总结】2022不忘初心,砥砺前行 2023纵有疾风起,人生不言弃。

2022 工作 砥砺前行 跨境电商跑路 2022年3月,从一家小跨境电商被动跑路,果断处于迷茫期,被动跑路的最好优势就是有赔偿,哈哈,怎么还有一丢丢高兴呢。简单总结了下在该公司的经历,是之前的老大带我去的&am…

如何通过产品帮助中心减轻客服压力,提高内部人员工作效率

客户的问题一直在重复,客服人员压力山大 客户不愿接听客服电话,产品问题难以解决 下班时间休息日,产品问题找谁问? 这些关于客户服务的老问题们困扰着许多产品方多年 要解决以上问题,更好地满足顾客需求。 搭建帮…

基于javaweb(springboot+mybatis)生活美食分享平台管理系统设计和实现以及文档报告

基于javaweb(springbootmybatis)生活美食分享平台管理系统设计和实现以及文档报告 博主介绍:5年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎…

详解函数指针(●‘◡‘●)☞

本文紧接于http://t.csdn.cn/78wbF 这篇一.函数指针数组\ ( >O< ) /1.书写形式&#xff1a;由函数指针内部*变量名>*变量名[n]&#xff1b; 2.使用&#xff1a;函数指针数组的用途&#xff1a;转移表 例如&#xff1a;模拟计算器&#xff1a;#include<stdio.h> …

用了这么久 IDEA,你还没用过 Live Templates 吗?

大家好&#xff0c;我是风筝&#xff0c;公众号「古时的风筝」&#xff0c;专注于 Java技术 及周边生态。 Live Templates 是什么&#xff0c;听上去感觉挺玄乎的。有的同学用过之后觉得简直太好用了&#xff0c;不能说大大提高了开发效率吧&#xff0c;至少也是小小的提高一下…

Qt创建项目:手把手创建第一个Qt项目

上一节介绍了QtCreator编辑器的页面长什么样子&#xff0c;以及都有哪些功能区&#xff0c;每个功能区都是用来做什么的。这一节我就手把手带大家创建一个Qt项目。 创建项目 点击新建按钮 创建项目有两个入口&#xff0c;一个是在欢迎页面的projects中点击New(新建)按钮&…

未来,勒索软件会呈现何种发展态势?

尽管过去一年里&#xff0c;全世界大约花费了1500亿美元在网络安全领域上&#xff0c;却无法真正阻止黑客攻击。在过去一年里&#xff0c;针对医院、学校、政府的勒索软件越来越多&#xff1b;加密货币领域也有无休止的黑客盗窃事件&#xff1b;还有针对微软、英伟达、Rockstar…

CORS跨域通信

在上一集的坐牢文章中&#xff0c;我们介绍了非官方的很多中方案&#xff0c;其中不乏一些江湖秘术。今天的这个&#xff0c;绝对的正统&#xff0c;纯正的官方打造。我们赶紧来看看。 1.什么是CORS&#xff1f; CORS 是一个 W3C 标准&#xff0c;全称是“跨域资源共享”&…

Prometheus的使用

Prometheus 是一个开放性的监控解决方案&#xff0c;用户可以非常方便的安装和使用 Prometheus 并且能够非常方便的对其进行扩展。 在Prometheus的架构设计中&#xff0c;Prometheus Server 并不直接服务监控特定的目标&#xff0c;其主要任务负责数据的收集&#xff0c;存储并…

ArcGIS Engine基础(31)之使用仿射变换对矢量数据进行空间校正

在生产数据过程中&#xff0c;因每个工程项目都可能有自己的施工坐标系&#xff0c;难免会产生数据提供方与数据使用方采用的坐标系不一致&#xff0c;造成数据在不同坐标系下存在一定偏移、旋转、缩放等&#xff0c;为了让数据能够在新坐标系准确定位&#xff0c;需要进行空间…

kitti数据集理解及可视化

kitti数据集简介 kitti数据集是比较早出来的3D检测方面的数据集&#xff0c;相对来说数据结构简单&#xff0c;适合做单目检测的工作&#xff0c;目前也是业界和学术界常用的公开数据集。 自己最近也在做单目3D检测的工作&#xff0c;所以也分享一些理解&#xff0c;希望能给到…

微服务自动化管理【Docker跨主机集群之Flannel】

环境说明 CentOS7 etcd-v3.4.3-linux-amd64.tar.gz flannel-v0.11.0-linux-amd64.tar.gz 官方文档&#xff1a;https://github.com/coreos/flannel 下载地址&#xff1a;https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64.tar.gz 1.…

verilog学习笔记- 9)流水灯实验

目录 简介&#xff1a; 实验任务&#xff1a; 硬件设计&#xff1a; 程序设计&#xff1a; 下载验证&#xff1a; 简介&#xff1a; LED&#xff0c;又名发光二极管。LED 灯工作电流很小&#xff08;有的仅零点几毫安即可发光&#xff09;&#xff0c;抗冲击和抗震性能好&…