【Spring声明式事务失效的12种场景测试】

文章目录

    • 一.Spring声明式事务是什么?
    • 二.Spring事务失效的12种场景
      • 1.访问权限问题
    • 小结

一.Spring声明式事务是什么?

Spring声明式事务是一种通过配置的方式管理事务的方法,它通过注解或XML配置来声明哪些方法需要事务管理,从而将事务管理逻辑与业务逻辑分离,简化了代码的复杂度,提高了代码的可读性和可维护性。‌

声明式事务的核心在于通过AOP(面向切面编程)技术实现事务管理的自动化。开发者只需在需要事务管理的方法上添加@Transactional注解,Spring框架会自动在方法执行前后进行事务的开启和关闭,以及在出现异常时进行事务的回滚。这种方式使得开发者可以专注于业务逻辑的实现,而不需要编写繁琐的事务管理代码‌。

具体实现方式上,声明式事务可以通过注解或XML配置来实现。使用注解方式时,只需在方法上添加@Transactional注解,Spring会自动处理事务的开启、提交和回滚。使用XML配置方式时,需要在Spring配置文件中进行相应的配置,指定哪些方法需要事务管理。这两种方式都使得事务管理的细节被屏蔽,开发者无需关心事务的具体实现细节‌

二.Spring事务失效的12种场景

在这里插入图片描述
我们在前面文章中了解过Spring编程式事务,看过Spring声明式事务源码的小伙伴们应该也清楚Spring声明式事务底层是借助于AOP+声明式事务去做的。我们知道Mybatis是基于数据源的方式,其编程式事务依赖于PlatformTransactionManager接口的实现DataSourceTransactionManager事务管理器进行事务管理(开启、提交、回滚)的。
所以我们使用Spring声明式事务需要往Spring容器中注入事务管理器所需的相关bean信息。

//在Spring开启声明式事务支持时,启动类需要加@EnableTransactionManagement注解。‌ 
//这个注解告诉Spring容器要启用基于注解的事务管理功能,否则事务不生效
@EnableTransactionManagement
@ComponentScan({"com.jinbiao.spring_study.transactionTest"})
@Configuration
public class JDBCConfig {@Beanpublic DataSource dataSource(){DruidDataSource druidDataSource = new DruidDataSource();druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");druidDataSource.setUrl("jdbc:mysql://localhost:3306/study_test");druidDataSource.setUsername("root");druidDataSource.setPassword("123456");return druidDataSource;}/*** 如果使用到mybatis需要给sqlSessionFactoryBean注入数据源信息* @param dataSource* @return*/@Beanpublic SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);return sqlSessionFactoryBean;}@Beanpublic JdbcTemplate jdbcTemplate(){return new JdbcTemplate(dataSource());}@Beanpublic PlatformTransactionManager transactionManager(){DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();transactionManager.setDataSource(dataSource());return transactionManager;}
}

1.访问权限问题

事务方法使用 final 、static 修饰方法。
static 静态方法属于类本身的而非实例,代理对象是无法对静态方法进行代理或拦截的。

小伙伴们仔细想想,静态方法是在构造方法之前执行的,对象是通过构造方法创建的,jdk动态代理或者cglb动态代理都是针对目标对象增强生成代理对象。这样一想静态方法怎么被代理对象增强对吧!(说人话:静态方法被调用的时候,对象都还没创建,代理对象都还没出生呢,所以事务怎么生效对吧~)

  • 测试事务方法使用static 修饰,无法回滚问题。
  1. 错误的测试方式:
   @Autowiredprivate static JdbcTemplate jdbcTemplate;/*** 测试事务失效1:访问权限问题:事务方法使用 static修饰方法*/@Transactionalpublic static void test1() {/*** 静态方法里面直接从Spring容器里面取jdbcTemplate此时会为null,会报空指针* 需要用在bean初始化前方法里面填充好的userServiceTransaction对象的jdbcTemplate。*/jdbcTemplate.execute("insert into jinbiao_user values (1,'rise1','wang1234..','10086','小程序')");throw new RuntimeException("异常啦,请回滚...");}

静态方法只能调用静态属性(不然程序编译期报错),我们注入的时候,把Spring容器里面的这个jdbcTemplate 使用static修饰升级为类变量,会报空指针,原理上面已解释:静态方法被调用的时候,对象都还没创建当然报空指针。
在这里插入图片描述
2. 正确的测试方式:

  1. 在Spring生命周期中,@PostConstruct注解的方法是在属性填充之后执行的,此时的this是填充好属性jdbcTemplate的。
  2. 所以我们在bean初始化前方法里面用填充好属性的this对象赋值给静态成员变量userServiceTransaction
  3. 通过静态成员变量userServiceTransaction的属性jdbcTemplate来执行sql。
 	@Autowiredpublic static UserServiceTransaction userServiceTransaction;@Autowiredprivate JdbcTemplate jdbcTemplate;@PostConstructpublic void init(){userServiceTransaction = this;}/*** 测试事务失效1:访问权限问题:事务方法使用 static修饰方法*/@Transactionalpublic static void test1() {/*** 静态方法里面直接从Spring容器里面取jdbcTemplate此时会为null,会报空指针* 需要用在bean初始化前方法里面填充好的userServiceTransaction对象的jdbcTemplate。*/userServiceTransaction.jdbcTemplate.execute("insert into jinbiao_user values (1,'rise1','wang1234..','10086','小程序')");throw new RuntimeException("异常啦,请回滚...");}

测试结果:数据没回滚。
在这里插入图片描述

  • 测试事务方法使用final 修饰,无法回滚问题。
    final 修饰的方法不能被子类重写,事务相关的逻辑无法插入到 final 方法中,代理机制无法对 final 方法进行拦截或增强。

下班了,未完持续….

小结

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

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

相关文章

JRT怎么从IRIS切换到PostGreSql库

1.执行M导出得到建库脚本文件 2.下载生成的脚本到本地D盘 3.修改驱动为PostGreSql 4.修改连接串 5.到PostGreSql里面创建一个jrtlis的数据库,模式为jrt 6.启动网站点击导入脚本按钮 导入完成了就可以正常使用PostGreSql库了

OpenCV高级图形用户界面(14)交互式地选择一个或多个感兴趣区域函数selectROIs()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 允许用户在给定的图像上选择多个 ROI。 该函数创建一个窗口,并允许用户使用鼠标来选择多个 ROI。控制方式:使用空格键或…

Google FabricDiffusion:开启3D虚拟试穿新篇章

随着数字化转型的步伐不断加快,时尚界也在探索如何利用最新技术为消费者带来更加沉浸式的购物体验。在这一背景下,Google 推出了一项名为 FabricDiffusion 的新技术,这项技术能够将2D服装图像中的高质量织物纹理转移到任意形状的3D服装模型上,从而为3D虚拟试穿提供了更为真…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于AGCN-LSTM模型的海上风电场功率概率预测 》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

端到端自动驾驶模型SparseDrive部署过程

SparseDrive 论文链接 https://arxiv.org/pdf/2405.19620 仓库链接 https://github.com/swc-17/SparseDrive 论文和模型的相关介绍大家可以参考其他博客的介绍,这里只介绍模型部署的过程和中间可能遇到的问题解决办法,以及代码解析和使用记录。 模型部署…

CyberRT通信介绍与基于Reader、Writer的通信实践(apollo9.0)

目录 数据通信场景 CyberRT中的通信方式 ​编辑 通信模式 话题通信 服务通信 参数通信 protobuf protobuf简介 protobuf文件编写 topic通信实验 实验环境 实验准备 代码编写 定义消息格式 发送消息 接收消息 定义编译规则 程序编译 运行程序 数据通信场景 …

fabric-sdk-go

Fabric-SDK-go 区块链网络搭建fabric-sdk代码代码结构:代码eg: 区块链网络搭建 使用fabric-sample的网络结构用容器搭建起测试网络即可。 fabric-sdk代码 代码很简易,主要为了了解怎么使用fabric为编程人员提供的sdk从而提供HTTP接口的情况…

浅谈华为 HarmonyOS Next

1. 万物互联时代的新机遇 随着万物互联时代的到来,智能应用从几十亿部手机扩展到数百亿个IoT设备,深刻改变了人们的生活方式。这为我们应用开发者带来了新的机遇和挑战。 机遇 : 目前正处于万物互联时代的前夕,正在经历手机单设备到全场景多…

技术分享:A-23OH型树脂在汽车涂装废溶剂回收中的应用

在当今汽车制造业竞争激烈的环境下,提高生产效率、降低成本的同时,满足环保要求已成为各制造商追求的核心目标。水性涂料因其环保、节能等多重优势,在汽车涂装领域的应用日益广泛。然而,随之而来的喷涂废溶剂处理问题也日益凸显。…

从 Hadoop 迁移到数据 Lakehouse 的架构师指南

从 Hadoop 到数据湖仓一体架构的演变代表了数据基础架构的重大飞跃。虽然 Hadoop 曾经以其强大的批处理能力统治着大数据领域,但如今的组织正在寻求更敏捷、更具成本效益和现代化的解决方案。尤其是当他们越来越多地开始实施 AI 计划时。根本没有办法让 Hadoop 为 A…

三周精通FastAPI:1 第一步入门

FastAPI是一个非常棒的python web和api框架,准备用三周的时间“精通它” 学习流程参考FastAPI官网的用户教程:教程 - 用户指南 - FastAPI 学前提示 运行代码 所有代码片段都可以复制后直接使用(它们实际上是经过测试的 Python 文件&#x…

UG NX12.0建模入门笔记:1.0 UG NX12.0安装教程

一、如何关闭防火墙? 提示:安装软件之前,建议先 关闭防火墙和杀毒软件!!! 文章目录 一、如何关闭防火墙?二、UG NX12.0安装包三、UG NX12.0安装教程1.新建文件夹2.安装JAVA环境3.安装许可证管理…

LeetCode_2235. 两整数相加_java

1、问题 2235. 两整数相加https://leetcode.cn/problems/add-two-integers/ 给你两个整数 num1 和 num2,返回这两个整数的和。 示例 1: 输入:num1 12, num2 5 输出:17 解释:num1 是 12,num2 是 5 &am…

智慧监管:EasyCVR视频汇聚智能分析平台助力有限空间作业实现全天候可视化监控

随着工业化和城市化进程的加快,有限空间作业(如地下管道、储罐、隧道等)在各类企事业单位中日益频繁。然而,这类作业环境复杂、危险系数高,对作业人员的安全管理和实时监控提出了严峻挑战。为了保障有限空间作业的安全…

021_Thermal_Transient_in_Matlab统一偏微分框架之热传导问题

Matlab求解有限元专题系列 固体热传导方程 固体热传导的方程为: ρ C p ( ∂ T ∂ t u t r a n s ⋅ ∇ T ) ∇ ⋅ ( q q r ) − α T d S d t Q \rho C_p \left( \frac{\partial T}{\partial t} \mathbf{u}_{\mathtt{trans}} \cdot \nabla T \right) \nab…

开发一个微信小程序要多少钱?

在当今数字化时代,微信小程序成为众多企业和个人拓展业务、提供服务的热门选择。那么,开发一个微信小程序究竟需要多少钱呢? 开发成本主要取决于多个因素。首先是功能需求的复杂程度。如果只是一个简单的信息展示小程序,功能仅限…

Hadoop集群基础搭建

目录 一.虚拟机安装 1.配置虚拟机的ip 2.配置本机的ip 3.新建虚拟机 4.克隆三台虚拟机 二.虚拟机网络配置 1.修改ip配置 2.配置主机名和主机映射 3.配置SSH免密登陆 三.安装JDK 1.tar命令解压JDK安装包 2.配置JDK的环境变量 四.安装Hadoop 1.tar命令解压Hadoop安…

快速了解kubernetes中的存储管理

目录 一 configmap 1.1 configmap的功能 1.2 configmap的使用场景 1.3 configmap创建方式 1.3.1 字面值创建 1.3.2 通过文件创建 1.3.3 通过目录创建 1.3.4 通过yaml文件创建 1.3.5 configmap的使用方式 1.3.5.1 使用configmap填充环境变量 1.3.5.2 通过数据卷使用c…

RestTemplate 学习笔记

简介 RestTemplate是一个执行HTTP请求的同步阻塞式工具类,它仅仅只是在 HTTP 客户端库(例如 JDK HttpURLConnection,Apache HttpComponents,okHttp 等)基础上,封装了更加简单易用的模板方法 API&#xff0c…

Renesas R7FA8D1BH (Cortex®-M85) 上光电编码器测速功能

目录 概述 1 软硬件 1.1 软硬件环境信息 1.2 开发板信息 1.3 调试器信息 2 硬件架构 2.1 硬件框架结构 2.2 测速功能原理介绍 2.2.1 理论描述 2.2.2 实现原理 2.2.3 系统硬件结构 3 软件实现 3.1 FSP配置项目 3.2 代码实现 3.2.1 初始化函数 3.2.2 功能函数 3.…