Spring事务管理:应用实战案例和规则

d5c2764c70959b3a0a4cb4c221f437ad.jpeg

背景

想象一下,如果没有Spring框架对事务的支持,我们得自行对事物进行管理:

  • 获得JDBC连接、

  • 关闭JDBC连接、

  • 执行JDBC事务提交、

  • 执行JDBC事务回滚操作

有了Spring事务框架,我们再也不需要在与事务相关的方法中处理大量的try...catch...finaly代码。

话说在前,Spring 中事务的使用虽然已经相对简单得多,但是,还是有很多的使用及配置规则。

事务管理,本质是AOP的应用。

规则

规则1:Spring事务只针对RuntimeException

默认情况下 Spring 中的 事务处理只对 RuntimeException 方法进行回滚,所以,如果 此处将 Runtime Exception 替换成普通的 Exception 不会产生回滚 效果 。

规则2:声明注解@Transactional同时在类和方法标识,方法级别会覆盖类级别

方法注解->类注解->接口方法注解->接口类注解

对于事务属性的获取规则相信大家都已经很清楚,如果方法中存在事务属性,则使用方法 上的属性,否则使用方法所在的类上的属性,如果方法所在类的属性上还是没有搜寻到对应的 事务属性,那么再搜寻接口中的方法,再没有的话,最后尝试搜寻接口的类上面的声明 。  

规则3:事务失效场景

Spring事务在什么情况下会失效?

1.访问权限问题

java的访问权限主要有四种:private、default、protected、public,它们的权限从左到右,依次变大。

如果事务方法的访问权限不是定义成public,这样会导致事务失效,因为spring要求被代理方法必须是public的。

2.方法用final修饰

如果事务方法用final修饰,将会导致事务失效。因为spring事务底层使用了aop,也就是通过jdk动态代理或者cglib,帮我们生成了代理类,在代理类中实现的事务功能。

3.对象没有被spring管理

使用spring事务的前提是:对象要被spring管理,需要创建bean实例。如果类没有加@Controller、@Service、@Component、@Repository等注解,即该类没有交给spring去管理,那么它的方法也不会生成事务。

4.数据库引擎不支持事务

如果MySQL使用的存储引擎是myisam,这样的话是不支持事务的。因为myisam存储引擎不支持事务。

5.通过this进行方法内部调用

如下代码所示,update方法上面没有加 @Transactional 注解,调用有 @Transactional 注解的 updateOrder 方法,updateOrder 方法上的事务会失效。

因为发生了自身调用,调用该类自己的方法,而没有经过 Spring 的代理类,只有在外部调用事务才会生效。

6.未开启事务

如果是spring项目,则需要在配置文件中手动配置事务相关参数。如果忘了配置,事务肯定是不会生效的。

如果是springboot项目,那么不需要手动配置。因为springboot已经在DataSourceTransactionManagerAutoConfiguration类中帮我们开启了事务。

7.吞了异常

有时候事务不会回滚,有可能是在代码中手动catch了异常。因为开发者自己捕获了异常,又没有手动抛出,把异常吞掉了,这种情况下spring事务不会回滚。

实战案例

启动类

使用@EnableTransactionManagement开启事务管理。

@EnableDiscoveryClient
@SpringBootApplication
//测试自定义启动类加载
@EnableSpringStudy
@EnableCircuitBreaker
//mapper扫描的包路径
@MapperScan("com.bryant.mapper")
@EnableTransactionManagement
@EnableWebMvc
publicclassUserServer{
    publicstaticvoidmain(String[]args){
        SpringApplication.run(UserServer.class,args);
    }
}

声明式事务

Spring的声明式事务是通过AOP实现的(环绕通知)开发中经常使用(代码侵入性最小)–推荐使用!

@Transactional(propagation=Propagation.REQUIRED,readOnly=false)
@PostMapping("/user/add_with_ex")
public void addUserWithEx(Useruser)
{
    longid = newRandom().nextLong();
    UserDetaildetail=UserDetail.builder()
        .id(id)
        .age(newRandom().nextInt(100))
        .email(newRandom().nextInt(100000000)+"@qq.com")
        .name("bryant"+newRandom().nextInt(1111))
        .tenantId(newRandom().nextLong())
        .build();
    userService.insert(detail);
    throw new NullPointerException("addUserWithEx...");
}

编程式事务

通过TransactionTemplate手动管理事务在实际应用中很少使用,原因是要修改原来的代码,加入事务管理代码(侵入性 )

@PostMapping("/user/add_with_ex2")
public void addUserWithEx2(User user)
{
    long id = new Random().nextLong();
    transactionTemplate.execute(
            new TransactionCallbackWithoutResult() {
                @Override
                protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                    UserDetail detail = UserDetail.builder()
                            .id(id)
                            .age(new Random().nextInt(100))
                            .email(new Random().nextInt(100000000) + "@qq.com")
                            .name("bryant" + new Random().nextInt(1111))
                            .tenantId(new Random().nextLong())
                            .build();
                    userService.insert(detail);
                    throw new NullPointerException("addUserWithEx...");
                }
            }
    );
}

测试效果

插入操作,最终以为异常被事务切面捕获,从而执行了回滚逻辑。

拓展:PROPAGATION_REQUIRED和PROPAGATION_NESTED区别

PROPAGATION_REQUIRED 和 PROPAGATION_NESTED 是 Spring 框架中事务传播行为的两种类型。

它们之间的主要区别在于如何处理嵌套事务以及事务回滚的行为。

PROPAGATION_REQUIRED是默认的事务传播行为。

当一个事务方法被另一个事务方法调用时:

PROPAGATION_REQUIRED 表示:

  1. 如果当前没有事务,就新建一个事务。

  2. 如果已经存在一个事务,就加入到这个事务中。

这意味着,如果在一个事务方法中调用了另一个带有 PROPAGATION_REQUIRED 的事务方法,那么这两个方法将在同一个事务中执行。如果其中一个方法失败并抛出异常,整个事务将回滚。

PROPAGATION_NESTED 表示:

  1. 如果当前没有事务,就新建一个事务。

  2. 如果已经存在一个事务,就在当前事务中创建一个保存点(savepoint),然后开启一个嵌套事务。

嵌套事务的特点是,它可以独立于外部事务进行回滚。如果嵌套事务失败并抛出异常,它将回滚到保存点,而不会影响外部事务。如果外部事务失败并回滚,嵌套事务也会被回滚。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Faker:自动化测试数据生成利器

Faker:自动化测试数据生成利器 前言1. 安装2. 多语言支持3. 常用方法3.1 生成姓名和地址3.2 生成电子邮件和电话号码3.3 生成日期和时间3.4 生成公司名称和职位3.5 生成文本和段落3.6 生成图片和颜色3.7 生成用户代理和浏览器信息3.8 生成文件和目录3.9 生成UUID和哈…

4 机器学习之归纳偏好

通过学习得到的模型对应了假设空间中的一个假设。于是,图1.2的西瓜版本空间给我们带来一个麻烦:现在有三个与训练集一致的假设,但与它们对应的模型在面临新样本的时候,却会产生不同的输出。例如,对(色泽青绿…

Excel日期导入数据库变为数字怎么办

在Excel导入到数据库的过程中,经常会碰到Excel里面的日期数据,导进去过后变成了数字。 如下图: 使用navicate等数据库编辑器导入数据库后: 原因分析:这是因为日期和时间在excel中都是以数字形式存储的,这个…

PolarCTF靶场[web]file、ezphp WP

[WEB]file 知识点:文件上传漏洞 工具:Burp Suite、dirsearch 方法一: 根据页面提示,先用dirsearch工具扫一扫 访问/upload.php,发现一个上传区 在访问/uploaded/,再点击Parent Directory,发现链接到首页…

带隙基准Bandgap电路学习(三)

一、导入器件到版图中 从原理图中导入器件: Connectivity——>Generate——>All From Source I/O Pins暂不添加,后面自己画 PR(Primary Region)Boundary: 通常是用来定义芯片设计中某些关键区域的轮廓,比…

用Eclipse运行第一个Java程序

1.左键双击在桌面“软件 (文件夹)”,打开该文件夹 2.左键双击“eclipse (文件夹)”,打开该文件夹 3.左键双击“eclipse (文件夹)”,打开该文件夹 4.左键双击“eclipse.exe”,运行这个可执行程序 5.左键单击“Ok(按下按…

【软件部署安装】OpenOffice转换PDF字体乱码

现象与原因分析 执行fc-list查看系统字体 经分析发现,linux默认不带中文字体,因此打开我们本地的windows系统的TTF、TTC字体安装到centos机器上。 安装字体 将Windows的路径: C:\Windows\Fonts 的中文字体,如扩展名为 TTC 与TT…

电影《荒野机器人》观后感

上上周看了电影《荒野机器人》,电影整体是比较偏向温馨的,通过动物与机器人视角,展现人类为情感。 (1)承载-托举-学习-感情 在电影中,有个场景让自己感觉特别温馨,就是机器人为了让大雁宝宝学习…

Linux系统之dig命令的基本使用

Linux系统之dig命令的基本使用 一、dig命令介绍二、本次实践环境三、dig命令的使用帮助3.1 dig的语法解释3.2 dig的帮助信息 四、dig命令的基本使用4.1 查询对应域名的ip4.2 查询域名的MX记录4.3 查询域名的NS记录4.4 查询域名的A记录4.5 查询详细信息4.6 对目标ip进行反向解析…

让Kimi像人类思考的“Kimi探索版“已开启灰度内测!GPT-o1贡献者之一宣布离职|AI日报

文章推荐 “AI教父”辛顿与物理学家霍普菲尔德荣获诺贝尔物理学奖!“AI教母”李飞飞选择谷歌云作为主要计算提供商|AI日报 今日热点 o1推理模型贡献者Luke Metz官宣从OpenAI离职 就在昨日,o1推理模型贡献者之一Luke Metz发文称自己经过两…

Spring Boot实现License生成与校验详解

​ 博客主页: 南来_北往 系列专栏:Spring Boot实战 在软件开发领域,License(许可证)机制是保护软件版权、控制软件使用范围的重要手段。通过为软件生成唯一的License,开发者可以确保只有合法用户才能使用软件&…

【LeetCode】每日一题 2024_10_15 三角形的最大高度(枚举、模拟)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动! 题目:三角形的最大高度 代码与解题思路 久违的简单题 这道题读完题目其实不难想到有两条路可以走: 1、题目很明显只有两种情况,枚举是第一个球是红球还是蓝球这两种情…

LIN诊断帧结构与仿真详解

在之前的文章中介绍了LIN主、从节点各自如何去做诊断测试,不太清楚的可以移步:LIN协议的诊断测试(附CAPL自动化代码) 文章目录 一、LIN诊断帧的帧结构二、诊断数据内容分析三、仿真测试实战 一、LIN诊断帧的帧结构 LIN诊断帧分为…

ClickHouse入库时间与实际相差8小时问题

原因一:服务端未修改默认时区 解决方案: 1、找 ClickHouse 配置文件 config.xml,通常位于 /etc/clickhouse-server/ 目录。 2、编辑 config.xml 文件,找到 标签。如果标签不存在,需要手动添加。 3、修改 标签的内容为 …

Prometheus + Grafana 监控 MySQL 数据库

文章目录 1、前置介绍2、搭建流程2.1、安装 Docker2.2、安装 MySQL2.3、安装 MySQL Exporter2.4、安装 Prometheus2.5、安装 Grafana 1、前置介绍 本次监控平台搭建,我使用2台阿里云服务器来完成本次的搭建部署操作,配置如下: 阿里云ECS1&am…

电脑无法无线投屏的解决办法

在前司的时候经常遇到电脑无法使用无线投屏器的情况,今天就来聊聊如何解决。 1.不会连接。这种情况,经常发生在WIN10升级WIN11之后,一般是两种办法,一种是同时按键盘上的WINDOWS和K键,右下角就会出来连接的图标&#…

Spring Boot课程答疑:技术难题一网打尽

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式,是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示: 图4-1系统工作原理…

Spring Integration + MQTT

1. 简介 Spring Integration: Spring Integration是一个开源的Java库,用于构建基于消息的应用程序。它提供了一套丰富的组件和工具,使得开发者可以轻松地开发出可靠、灵活和可扩展的集成解决方案。以下是Spring Integration的一些主要用途&…

Webpack 完整指南

​🌈个人主页:前端青山 🔥系列专栏:Webpack篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来webpack篇专栏内容:webpack介绍 目录 介绍 一、webpack 1.1、webpack是什么 1.2 webpack五个核心配置 1.…

浏览器服务端文件下载控制(安全阻止、文件浏览器打开还是下载行为控制)

文章目录 简介Chrome已阻止不安全内容下载PDF直接打开txt、xml、js文件被自动打开了而不是下载阿里OSS设置response header阿里OSS修改metadata 简介 随着浏览器的发展,有很多安全方面的限制,对我们的文件下载行为产生了很大的影响。 在JavaScript下载…