【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.rhkb.cn/news/451413.html

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

相关文章

杨氏矩阵(有一个数字矩阵,矩阵的每行从左到右的递增的,矩阵从上到下是递增的请编写一个程序,在这样的矩阵中查找某个数字是否存在)

//杨氏矩阵 //有一个数字矩阵&#xff0c;矩阵的每行从左到右的递增的&#xff0c;矩阵从上到下是递增的 //请编写一个程序&#xff0c;在这样的矩阵中查找某个数字是否存在 // 1 2 3 // 4 5 6 // 7 8 9 #include<stdio.h> int main() {int a[3][3] { 0 };int i 0, j …

数据库管理-第252期 深入浅出多主多活数据库技术- Cantian存储引擎(二)(20241017)

数据库管理252期 2024-10-17 数据库管理-第252期 深入浅出多主多活数据库技术- Cantian存储引擎&#xff08;二&#xff09;&#xff08;20241017&#xff09;1 部署规划2 服务器基础配置2.1 配置HOSTS2.2 关闭防火墙2.3 关闭SELinux2.4 配置yum源 3 编译服务器配置3.1 安装git…

Vue Google 广告的配置

前置条件&#xff1a;已经在Google AdSense 中 添加网站 并通过审核 同时已创建广告单元。 因 VUE 的 Script 配置问题&#xff0c;所以不能直接拷贝内容。 index.html 配置 添加 Google 广告的脚本。 //index.template.html /* * 在head标签中添加 script 【 **** 】&#…

网络变压器在PCIe网口应用的案例

PCIe&#xff08;Peripheral Component Interconnect Express&#xff09;是一种高速串行计算机总线标准&#xff0c;用于连接计算机主板上的设备&#xff0c;如显卡、网络适配器、存储控制器等。H82422S 网络变压器&#xff08;Ethernet Transformer&#xff09;&#xff0c;在…

SSM框架学习(七、MyBatis-Plus高级用法:最优化持久层开发)

目录 一、MyBatis-Plus快速入门 1.简介 2.快速入门 二、MyBatis-Plus核心功能 1.基于Mapper接口CRUD &#xff08;1&#xff09;Insert 方法 &#xff08;2&#xff09;Delete方法 &#xff08;3&#xff09;Update 方法 &#xff08;4&#xff09;Select方法 2.基于Serv…

使用LangGraph构建多Agent系统架构!

0 前言 Agent是一个使用大语言模型决定应用程序控制流的系统。随着这些系统的开发&#xff0c;它们随时间推移变得复杂&#xff0c;使管理和扩展更困难。如你可能会遇到&#xff1a; Agent拥有太多的工具可供使用&#xff0c;对接下来应该调用哪个工具做出糟糕决策上下文过于…

重塑企业数字化未来:物联网与微服务架构的战略性深度融合

从物联网到微服务架构的战略价值解读 随着全球数字化转型的不断加速&#xff0c;企业需要重新审视其技术基础架构&#xff0c;以适应日益复杂的业务需求和市场变化。物联网&#xff08;IoT&#xff09;作为核心技术&#xff0c;已广泛应用于制造、农业、交通、医疗等各个行业&…

Qt 支持打包成安卓

1. 打开维护Qt&#xff0c;双击MaintenanceTool.exe 2.登陆进去,默认是添加或移除组件&#xff0c;点击下一步&#xff0c; 勾选Android, 点击下一步 3.更新安装中 4.进度100%&#xff0c;完成安装&#xff0c;重启。 5.打开 Qt Creator&#xff0c;编辑-》Preferences... 6.进…

比亚迪车机安装第三方应用教程

比亚迪车机安装第三方应用教程 比亚迪车机U盘安装APP&#xff0c; 无论是dlink3.0还是4.0都是安卓系统&#xff0c;因此理论上安卓应用是都可以安装的&#xff0c;主要就是横屏和竖屏的区别。在比亚迪上安装软件我主要推荐两种方法。 第一种&#xff0c;直接从电脑端下载安装布…

(01)fastapi的基础学习——开启学习之路

前言 性能极高&#xff0c;可与 NodeJS, Go 媲美。(得益于Starlette和Pydantic)。 Starlette 是一个轻量级 ASGI 框架/工具包。它非常适合用来构建高性能的 asyncio 服务&#xff0c;并支持 HTTP 和 WebSockets。 官方网址&#xff1a;Starlette Pydantic 是一个使用Python…

摇人摇人, JD内推岗位(社招+校招)

摇人摇人, 有找工作的家人们看过来啊~ 虚位以待, 快到碗里来 算法开发工程师岗 京东云 北京|T7, 5-10年 岗位职责&#xff1a; 参与基于RAG知识库平台和ChatBI产品打造和商业化落地&#xff0c;进行相关技术&#xff1a;包括OCR、文档拆分、意图理解、多轮对话、NL2SQL、Embed…

idea删除git历史提交记录

前言&#xff1a;此文章是我在实际工作中有效解决问题的方法&#xff0c;做记录的同时也供大家参考&#xff01; 一、 首先&#xff0c;通过idea的终端或系统的cmd控制台&#xff0c;进入到你的项目文件根目录&#xff0c;idea终端默认就是项目根目录。 二、确保你当前处于要删…

Bluetooth Channel Sounding中关于CS Step及Phase Based Ranging相应Mode介绍

目录 BLE CS中Step定义 BLE CS中交互的数据包/波形格式 BLE CS中Step的不同Mode BLE CS中Step的执行过程 Mode0介绍 Mode0 步骤的作用 Mode0步骤的执行过程 Mode0步骤的执行时间 Mode0步骤的时间精度要求 Mode2介绍 Mode2步骤的作用和执行过程 Mode2步骤的执行时间 B…

Vue3 集成Monaco Editor编辑器

Vue3 集成Monaco Editor编辑器 1. 安装依赖2. 使用3. 效果 Monaco Editor &#xff08;官方链接 https://microsoft.github.io/monaco-editor/&#xff09;是一个由微软开发的功能强大的在线代码编辑器&#xff0c;被广泛应用于各种 Web 开发场景中。以下是对 Monaco Editor 的…

Linux 阻塞和非阻塞 IO 实验

阻塞和非阻塞 IO 是 Linux 驱动开发里面很常见的两种设备访问模式&#xff0c;在编写驱动的时候一定要考虑到阻塞和非阻塞。本章我们就来学习一下阻塞和非阻塞 IO&#xff0c;以及如何在驱动程序中处理阻塞与非阻塞&#xff0c;如何在驱动程序使用等待队列和 poll 机制。 阻塞和…

【机器学习】聚类算法|KMeans实现流程|SSE误差平法和|SC轮廓系数法|顾客数据聚类分析案例

文章目录 聚类算法聚类算法简介聚类算法分类 聚类算法API案例 使用KMeans模型数据探索聚类 KMeans实现流程***模型评估方法误差平方和 SSE(The sum of squares due to error)“肘”方法 (Elbow method) - K值确定 SC轮廓系数法&#xff08;Silhouette Coefficient&#xff09;聚…

微服务--OpenFeign【重点】

如果哪天 我们硬编码写的接口变了&#xff0c;只要写过该接口的 都要改&#xff0c;太麻烦了&#xff0c; 所以 就用 OpenFeign 来解决这个麻烦 了解&#xff1a; SimpleClientHttpRequestFactory和 HttpComponentsClientHttpRequestFactory 都是Spring框架中用于创建ClientH…

sentinel原理源码分析系列(六)-统计指标

调用链和统计节点构建完成&#xff0c;进入统计指标插槽&#xff0c;统计指标在最后执行的&#xff0c;等后面的插槽执行完&#xff0c;资源调用完成了&#xff0c;根据资源调用情况累计。指标统计是最重要的插槽&#xff0c;所有的功能都依靠指标数据&#xff0c;指标的正确与…

尤雨溪都点赞的表单校验解决方案,到底多么强

尤雨溪都点赞的表单校验解决方案&#xff0c;到底多么强 如果你是 Vue 开发者&#xff0c;那么 Vorms 绝对是你不能错过的表单验证利器。本文将带你快速了解 Vorms 的基本功能、特点和如何简单使用它提升你的开发体验。 软件简介 Vorms 是一个基于 Vue 3 组合式 API 的表单验证…

STL——string类

前言 从本篇博客开始&#xff0c;就正式来介绍STL的正式内容&#xff0c;STL在C中的学习中非常重要&#xff0c;具有举足轻重的地位&#xff0c;这块儿内容会给我们提供很多现成的接口&#xff0c;可以大大简化我们的代码&#xff0c;我们之前用C语言写的代码将会被极大地简化…