【Spring】-编程式事务和声明式事务

spring中控制事务的方式有两种:编程式事务和声明式事务,今天我以两种事务出发,对spring中实现事务的@EnableTransactionManagement和@Transaction两个注解的底层原理进行讨论。

一、编程式事务

什么是编程式事务?

硬编码的方式实现事务,在代码中手动开始、提交和回滚事务

编程式事务实现思想是什么?

  • 配置PlatformTransactionManager事务管理器去控制事务
  • 配置TransactionDefinition设置事务属性
  • 配置TransactionTemplate控制事务

步骤和原理

1、定义数据源

2、定义一个PlatformTransactionManager 事务管理器,指定数据源。控制事务的操作(开始、提交、回滚)

3、定义TransactionDefinition 事务属性,可以配置事务属性信息

4、开启事务操作。通过调用getTransaction方法

补充:ThreadLocal中存储了datasource和connection的映射

这样当我们开启事务的时候会创建一个数据库连接,通过ThreadLocal保证线程的同步

5、执行业务操作

6、commit提交/rollback回滚事务

优缺点

优点:

以在代码中精确地控制事务的起始点、提交点和回滚点,实现更细粒度的事务管理。

缺点:

  1. 代码侵入性:编程式事务管理会将事务管理逻辑直接嵌入到业务代码中,增加了代码的复杂度和维护成本,使得业务逻辑与事务管理耦合在一起。
  2. 重复性工作:在多个业务方法中可能需要重复编写事务管理逻辑,增加了代码冗余和维护工作量。

二、声明式事务

什么是声明式事务?

通过配置的方式去管理事务,可以是xml配置文件,也可以使用spring提供的@Transactional注解

声明式事务实现思想是什么?

  • 添加@EnableTransactionManagement注解
  • 添加@Transactional注解

步骤和原理

1、启用事务管理功能-配置类上加上@EnableTransactionManagement注解

2、定义事务管理器

3、需要开启事务的目标接口/类/方法上添加@Transaction注解

4、执行业务逻辑

5、启动spring容器,获取bean执行业务逻辑

优缺点

优点:

  1. 与业务逻辑分离:声明式事务管理将事务管理逻辑从业务代码中分离出来,使得业务逻辑更清晰,降低了代码的耦合性。
  2. 配置简单:通过注解或XML配置,可以简单地定义事务的传播行为、隔离级别等属性,而无需在每个业务方法中编写重复的事务管理代码。
  3. 易于维护:由于事务管理逻辑集中在配置中,易于维护和修改,提高了代码的可读性和可维护性。
  4. 提高一致性:声明式事务管理可以确保在所有业务方法中都应用相同的事务管理策略,提高了事务管理的一致性。

缺点:

  1. 灵活性有限:声明式事务管理的灵活性相对较低,无法在运行时动态地改变事务管理策略,有一定的局限性。
  2. RPC远程调用成功,但是本地事务回滚了,RPC调用无法回滚。并且事务中有远程调用,会拉长整个事务,导致本地事务的数据库连接一致被占用,最后可能会导致数据库连接池耗尽

在阿里巴巴的开发手册中也明确标出,我们用@Transactional注解的时候要谨慎,大家在业务场景中要谨慎使用哦!


上面我已经对spring实现事务的两种方式分别进行了说明,下面我们看看它的源码,解开事务这个神秘面纱!

三、源码分析

@EnableTransactionManagement

作用是什么?

开启spring自动管理事务。在spring容器启动的时候,会拦截所有bean的创建,判断当前bean中有没有用@Transaction注解,是不是需要让spring管理事务

判断规则:

  • public方法上有没有用@Transaction注解
  • 和bean的类相关的类/接口上有没有用@Transaction注解

当满足规则之后会通过aop的方式创建代理,并且在代理中添加一个TransactionInterceptor拦截器

注意:@Transaction注解在代理对象被创建并且方法被调用时生效

@Transactional注解生效,必须确保Spring能够为目标类创建代理对象,并且方法通过代理对象调用

TransactionInterceptor拦截器的作用是什么?

拦截@Transaction方法,在方法前后添加事务额外逻辑

如果代理中还有其他拦截器,拦截器的顺序如何指定呢?

通过order()方法修改事务拦截器的执行顺序

注意:默认值是 LOWEST_PRECEDENCE = Integer.MAX_VALUE,拦截器的执行顺序是order升序

 int order() default Ordered.LOWEST_PRECEDENCE;

@Import(TransactionManagementConfigurationSelector.class)在这里的作用是什么?

@Import的作用是批量导入需要注册的类,完成bean的注册

那@Import导入了哪些类?

通过点进去TransactionManagementConfigurationSelector我们发现,里面有一个selectImports方法,这个方法的返回值是一个字符串数组,返回的字符串数组如果是正常的全限定类名才会被容器识别

通过查看selectImports方法源码,我们发现return了两个类-AutoProxyRegistrar、ProxyTransactionManageMentConfiguration,也就是说Import导入了这两个类

  1. AutoProxyRegistrar:启用spring aop功能,创建代理
  2. ProxyTransactionManageMentConfiguration:在aop中添加事务拦截器

①、AutoProxyRegistrar

点进源码,我们看registerBeanDefinitions这个方法,看过spring容器启动流程的小伙伴会发现,其中流程就会调用这个方法,AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry)作用是向spring容器注册一个自动代理创建器,从而启用AOP代理的功能

在方法内部会导入InfrastructureAdvisorAutoProxyCreator类,给spring 容器中注册了一个后置处理器-BeanPostProcessor,拦截所有bean的创建并将符合规则的bean创建代理,对类进行增强

在生命周期阶段,创建bean的时候只有需要增强,就会调用BeanPostProcessor的after进行增强

②、ProxyTransactionManageMentConfiguration

配置类,一般是提供加了@Bean的一些方法。注册了一个事务拦截器TransactionInterceptor

总:通过对上面两个导入的类的源码分析我们明确了他们的作用,我们使用@Transaction标注的bean会通过AutoProxyRegistrar去启用aop功能,通过ProxyTransactionManagementConfiguration在aop中添加事务拦截器从而实现事务管理

如果有想要交流的内容欢迎在评论区进行留言,如果这篇文档受到了您的喜欢那就留下你点赞+收藏+评论脚印支持一下博主~

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

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

相关文章

牛客NC197 跳跃游戏(一)【中等 动态规划 Java、Go、PHP】

题目 题目链接: https://www.nowcoder.com/practice/23407eccb76447038d7c0f568370c1bd 思路 答案说的merge区间就是每个A[i]的地方能跳到的最远坐标是A[i] [i], 有一个maxReach,遍历一遍A[i], 不断刷新MaxReach, 如果某个i 位置比maxReac…

MT3023 歌词中找单词

1.暴力 10/12 #include <bits/stdc.h> using namespace std; int n; string a[10005]; int main() {cin >> n;for (int i 0; i < n; i)cin >> a[i];string ll;cin >> ll;for (int i 0; i < n; i){string u a[i];int num 0;int j 0;for (in…

ssm056基于Java语言校园快递代取系统的设计与实现+jsp

校园快递代取系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本校园快递代取系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短…

【在线OJ】雪花算法代码实现

雪花算法 用一个64比特位的long类型来作为生成id的类型&#xff0c;首先我们要了解哪些位置对应的意义&#xff0c;其中在本项目中10位的工作机器id被细分位5bit的机房id与5bit的机器id。雪花算法支持每毫秒生成2的12次方-1个id。 用一个64比特位的long类型来作为生成id的类型…

unity制作拼接地图

前段时间有个朋友问我想要制作一款地图编辑器&#xff0c;最开始我还想着在一个平面用节点切割制作地图编辑器这倒是也行&#xff0c;但不太好控制每一个点&#xff0c;如果未来项目大了&#xff0c;更加不好维护。 偶然间翻到一篇文章&#xff1a;unity地图边缘检测 或许我们…

upload-labs第七八关

第七关 $is_upload false; $msg null; if (isset($_POST[submit])) {if (file_exists(UPLOAD_PATH)) {$deny_ext array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml"…

SaaS智慧工地云平台源码 支持二次开发、支持源码交付

目录 智慧工地云平台功能模块 一、劳务管理系统 二、视频监控系统 三、危大工程管理 四、环境监测系统 五、材料管理系统 六、进度管理系统 通过人员管理、车辆管理、视频监控、施工质量、设备管理、环境监测、能耗监测七大维度提供面向工程管理人员的现场综合指挥管理平…

51单片机工程模板的建立(基于STC15系列库)

一、开启前准备 1.STC15官方库文件 1.1 stc15-software-lib-v1.0.rar&#xff1b;下载地址&#xff1a;STC15系列库&#xff08;带使用手册&#xff09;资源-CSDN文库 2.Keil4_C51软件&#xff0c;或其它版本&#xff1b; 二、创建工程模板 1.建立文件分类 listing&#xf…

PyTorch深度学习之旅:从入门到精通的十个关键步骤

在人工智能的浪潮中&#xff0c;深度学习框架扮演着至关重要的角色。PyTorch作为其中的佼佼者&#xff0c;以其简洁、直观和灵活的特性&#xff0c;吸引了众多开发者与研究者。本文将引导您逐步掌握PyTorch&#xff0c;从基础概念到高级应用&#xff0c;让您在深度学习的道路上…

斯坦福发布法律指令数据集LawInstruct,统一17个辖区24种语言

在法律领域&#xff0c;语言模型&#xff08;Language Models, LLMs&#xff09;的发展一直面临着独特的挑战。法律文本的复杂性、专业术语的广泛使用以及对精确性和可靠性的极高要求&#xff0c;使得法律领域的自然语言处理&#xff08;Natural Language Processing, NLP&…

工业数学模型——高炉煤气发生量预测(三)

1、工业场景 冶金过程中生产的各种煤气&#xff0c;例如高炉煤气、焦炉煤气、转炉煤气等。作为重要的副产品和二次能源&#xff0c;保证它们的梯级利用和减少放散是煤气能源平衡调控的一项紧迫任务&#xff0c;准确的预测煤气的发生量是实现煤气系统在线最优调控的前提。 2、…

JRT在线初始化完善

之前实现的在线初始化留了个尾巴&#xff0c;那就是环境下载页构造zip包的时候没修改JRTBrowser的连接串地址为当前网站&#xff0c;这样就要求网站部署好之后给用户下载之前有人要把服务器的浏览器地址配置好。这样就增加一个运维工作&#xff0c;如果忘了或者不知道的人就会导…

基于SSM的计算机课程实验管理系统的设计与实现(内附设计LW + PPT+ 源码下载)

基于SSM的计算机课程实验管理系统的设计与实现 项目名称&#xff1a; 基于SSM的计算机课程实验管理系统的设计与实现 项目技术栈 该项目采用了以下核心技术栈&#xff1a; 后端框架/库&#xff1a; SSM (Spring Spring MVC MyBatis)数据库&#xff1a; MySQL前端技术&…

01 JavaScript学习 导读

什么是JavaScript&#xff1f; JavaScript 是一种用于创建交互式网页和网络应用程序的脚本语言。它是一种高级、动态类型的语言&#xff0c;广泛用于客户端网页开发&#xff0c;可以用来增强网页的交互性并实现各种功能。 以下是 JavaScript 的一些重要特点和用途&#xff1a;…

Linux中进程和计划任务

一.程序 1.什么是程序 &#xff08;1&#xff09;是一组计算机能识别和执行的指令&#xff0c;运行于电子计算机上&#xff0c;满足人们某种需求的信息化工具 &#xff08;2&#xff09;用于描述进程要完成的功能&#xff0c;是控制进程执行的指令集 二.进程 1.什么是进程…

ORAN C平面 Section Extension 23

ORAN C平面Section扩展23用于任意symbol模式的调制压缩参数。此section扩展允许为一个或多个“SymPrbPatterns”指定多组“mcScaleReMask、csf和mcScaleOffset”值。“SymPrbPattern”用于指定一组PRB&#xff0c;这些PRB可以跨越使用prbPattern指定的整个PRB范围&#xff08;频…

20240329-1-SVM面试题

SVM面试题 1. SVM直观解释 SVM&#xff0c;Support Vector Machine&#xff0c;它是一种二分类模型&#xff0c;其基本模型定义为特征空间上的间隔最大的线性分类器&#xff0c;间隔最大使它有别于感知机&#xff1b;其还包括核技巧&#xff0c;这使它成为实质上的非线性分类…

ACID模型是什么

ACID模型是什么 ACID模型是数据库管理系统中保证事务处理安全性的一组特性。ACID是原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consistency&#xff09;、隔离性&#xff08;Isolation&#xff09;和持久性&#xff08;Durability&#xff09;四个英文单词的…

使用 ECharts 绘制咖啡店各年订单的可视化分析

使用 ECharts 绘制咖啡店各年订单的可视化分析 在这篇博客中&#xff0c;我将分享一段使用 ECharts 库创建可视化图表的代码。通过这段代码&#xff0c;我们可以直观地分析咖啡店各年订单的情况。 饼图 这段代码包含了两个 ECharts 图表&#xff0c;一个是饼图&#xff0c;用…

lomobok源码编译学习笔记(1)

lomobok学习笔记&#xff08;1&#xff09; 项目导入 lombok的github地址 GitHub - projectlombok/lombok: Very spicy additions to the Java programming language. 开发工具 idea不知道为啥&#xff0c;装上ant工具也不好用&#xff0c;eclipse默认自带有ant,不需要装。…