当前位置: 首页 > news >正文

解密Spring事务生效的内部机制

声明式事务和编程式事务对比:

  1. 声明式事务:
    • 使用注解或XML配置的方式,在代码中声明事务的属性和行为。
    • 通过AOP和代理模式实现,将事务管理与业务逻辑代码解耦。
    • 适用于大多数情况,简化了代码,提高了可维护性和可读性。
    • 常用的注解是@Transactional,可以应用在方法或类级别。
  2. 编程式事务:
    • 在代码中显式编写事务管理的代码逻辑。
    • 需要手动控制事务的开启、提交和回滚等操作。
    • 适用于需要更细粒度控制事务的情况,或者在声明式事务不适用的情况下使用。
    • 可以使用编程式事务的API,如Spring的TransactionTemplate或JDBC的事务API。

Spring 事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,Spring 是无法提供事务功能的。对于纯 JDBC 操作数据库,想要用到事务,可以按照以下步骤进行(编程式事务同理)

1、获取连接 Connection con = DriverManager.getConnection()2、开启事务 con.setAutoCommit(true/false);3、执行 CRUD4、提交事务/回滚事务 con.commit() / con.rollback();5、关闭连接 conn.close();

在这里插入图片描述

当使用Spring的声明式事务后,我们可以只要写CRUD即可,其他由Spirng 自动完成。

本文主要讲解声明式事务

生效原理

下面是一个简单的示例,用于说明 Spring 事务的生效原理:

@Service
public class MyService {@Transactionalpublic void transferMoney(Account sourceAccount, Account targetAccount, double amount) {//省略逻辑处理}
}

声明式事务就是使用我们常见的@Transactional注解完成的,声明式事务优点就在于让事务代码与业务代码解耦,通过Spring中提供的声明式事务使用,我们也可以发觉我们只需要编写业务代码即可,而事务的管理基本不需要我们操心,Spring就像使用了魔法一样,帮我们自动完成了。

之所以那么神奇,本质还是依靠Spring框架提供的Bean生命周期相关回调接口和AOP结合完成的,简述如下:

这里思考下:如何保证同个线程请求时数据库多个操作使用的是同个Connection?

  • 通过自动代理创建器依次尝试为每个放入容器中的bean尝试进行代理
  • 尝试进行代理的过程对于事务管理来说,就是利用事务管理涉及到的增强器advisor,即TransactionAttributeSourceAdvisor
  • 判断当前增强器是否能够应用与当前bean上,怎么判断呢? —> advisor内部的pointCut喽 !
  • 如果能够应用,那么好,为当前bean创建代理对象返回,并且往代理对象内部添加一个TransactionInterceptor拦截器。
  • 此时我们再从容器中获取,拿到的就是代理对象了,当我们调用代理对象的方法时,首先要经过代理对象内部拦截器链的处理,处理完后,最终才会调用被代理对象的方法。(这里其实就是责任链模式的应用)
  • 当TransactionInterceptor的invoke()方法被执行时,它会先开启一个事务,然后再调用目标方法。如果目标方法执行成功,那么就会提交事务,否则就会回滚事务。
  • 在整个事务过程中,Spring会保证操作数据库时使用的是同一个连接。它是通过将一个数据库连接与一个ThreadLocal对象绑定起来,然后在需要操作数据库时通过该ThreadLocal对象来获取连接的。这样就可以避免多个连接导致的数据不一致问题。
    在这里插入图片描述

这里说下SpringBoot底层实现有一个AutoProxyRegistrar,简单来说,AutoProxyRegistrar顾名思义就是开启了AOP代理 ProxyTransactionManagementConfiguration是一个配置类,它又定义了另外三个bean:

  1. BeanFactoryTransactionAttributeSourceAdvisor:一个Advisor就是一个切面
  2. AnnotationTransactionAttributeSource:相当于Pointcut
  3. TransactionInterceptor:相当于中的 Advice,事务的拦截方法

AnnotationTransactionAttributeSource就是用来判断某个类上是否存在@Transactional注解, 或者判断某个方法上是否存在@Transactional注解的。

TransactionInterceptor就是代理逻辑,当某个类中存在@Transactional注解时,到时就产生一个 代理对象作为Bean,代理对象在执行某个方法时,最终就会进入到TransactionInterceptor的 invoke()方法。

对于被事务增强器TransactionAttributeSourceAdvisor代理的bean而言,代理对象内部会存在一个TransactionInterceptor,该拦截器内部构造了一个事务执行的模板流程:

protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,final InvocationCallback invocation) throws Throwable {//TransactionAttributeSource内部保存着当前类某个方法对应的TransactionAttribute---事务属性源//可以看做是一个存放TransactionAttribute与method方法映射的池子TransactionAttributeSource tas = getTransactionAttributeSource();//获取当前事务方法对应的TransactionAttributefinal TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);//定位TransactionManagerfinal TransactionManager tm = determineTransactionManager(txAttr);.....//类型转换为局部事务管理器PlatformTransactionManager ptm = asPlatformTransactionManager(tm);final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {//TransactionManager根据TransactionAttribute创建事务后返回//TransactionInfo封装了当前事务的信息--包括TransactionStatusTransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);Object retVal;try {//继续执行过滤器链---过滤链最终会调用目标方法//因此可以理解为这里是调用目标方法retVal = invocation.proceedWithInvocation();}catch (Throwable ex) {//目标方法抛出异常则进行判断是否需要回滚completeTransactionAfterThrowing(txInfo, ex);throw ex;}finally {//清除当前事务信息cleanupTransactionInfo(txInfo);}...//正常返回,那么就正常提交事务呗(当然还是需要判断TransactionStatus状态先)commitTransactionAfterReturning(txInfo);return retVal;}...

事务拦截器(TransactionInterceptor)的处理过程总结如下:

  1. 方法调用前的处理:事务拦截器在目标方法调用前执行一些预处理操作。这包括检查当前是否存在事务上下文(TransactionContext),如果不存在则创建新的事务上下文。事务上下文包含了事务的相关信息,如事务的传播行为、隔离级别、超时设置等。事务拦截器还会根据事务定义的属性决定是否开启新的事务或者加入已有的事务。

  2. 方法调用:事务拦截器将目标方法调用传递给实际的目标对象,并执行目标方法。

  3. 方法调用后的处理:在目标方法执行完成后,事务拦截器会根据方法的执行结果决定是提交事务还是回滚事务。如果方法执行过程中发生了异常,事务拦截器会触发事务回滚,将事务恢复到调用该方法之前的状态。如果方法执行成功,事务拦截器会触发事务提交,将事务的操作永久保存到数据库。

事务拦截器通过使用事务管理器(TransactionManager) 来协调和控制事务的开始、提交和回滚操作。事务管理器负责和底层的数据访问框架(如JDBC、Hibernate)进行交互,确保事务的一致性和隔离性。

事务拦截器是通过配置切面(Aspect)和切入点(Pointcut) 的方式与目标方法进行关联。切面定义了在何时何地应用事务拦截器,而切入点则定义了哪些方法会被事务拦截器拦截。通过配置切面和切入点,可以灵活地控制事务的应用范围。

相关文章:

解密Spring事务生效的内部机制

声明式事务和编程式事务对比&#xff1a; 声明式事务&#xff1a; 使用注解或XML配置的方式&#xff0c;在代码中声明事务的属性和行为。通过AOP和代理模式实现&#xff0c;将事务管理与业务逻辑代码解耦。适用于大多数情况&#xff0c;简化了代码&#xff0c;提高了可维护性和…...

大数据时代下的数据安全防护

随着大数据时代的来临&#xff0c;数据安全防护成为了一个重要的问题。在大数据时代&#xff0c;数据的规模和价值都得到了极大的提升&#xff0c;因此数据安全的重要性也变得越来越突出。本文将从数据加密、访问控制、网络安全和人员管理四个方面来介绍大数据时代下的数据安全…...

RabbitMQ-常用命令

RabbitMQ常用命令 3.1 启动停止rabbitMQ命令 # 前台启动Erlang VM 和 RabbitMQ 当窗口关闭或者ctrlc时&#xff0c;使退出了。 rabbitmq-server# 使用系统命令启动 systemctl start rabbitmq-server# 后台启动 rabbitmq-server -detached# 停止rabbitMQ和Erlang VM rabbitmq-…...

Spring中依赖注入的继承bean的细节问题

介绍 有时我们会对一种类型的bean进行继承&#xff0c;在Spring生成bean的时候&#xff0c;返回类型有时是子类类型&#xff0c;有时会父类类型。那么到底在什么情况下用哪种类型呢&#xff1f;肯定有不少人会忽略这点&#xff0c;本篇文章就是把这个细节讲清楚 案例 父类Ba…...

海外腾讯云服务器手机上无法访问外网怎么办??

本文将介绍腾讯云服务器无法访问外网的一些常见原因以及解决办法&#xff0c;同时解答了手机无法访问腾讯云服务器的问题。 腾讯云服务器&#xff08;Tencent Cloud Server&#xff09;是一种基于云计算技术的虚拟服务器&#xff0c;可以满足用户对于计算、存储、网络等方面的需…...

python3+requests:接口自动化测试(二)

前言&#xff1a;上篇文章python3requestsunittest&#xff1a;接口自动化测试&#xff08;一&#xff09;&#xff1a;已经介绍了基于unittest框架的实现接口自动化&#xff0c;但是也存在一些问题&#xff0c;比如最明显的测试数据和业务没有区分开&#xff0c;接口用例不便于…...

uni-app:允许字符间能自动换行(英文字符、数字等)

<template><view class"container"><!-- 这里是你的文本内容 -->{{ multilineText }}</view> </template><style> .container {word-break: break-all; } </style>例如&#xff1a; <template><view class"…...

day 42 |● 121. 买卖股票的最佳时机 ● 122.买卖股票的最佳时机II

121. 买卖股票的最佳时机 dp数组需要记录两种状态&#xff0c;一种是当天时手中还持有股票&#xff0c;一种是当天时手中已卖出股票。 func maxProfit(prices []int) int {dp : make([][]int, len(prices))dp[0] []int{-prices[0], 0}for i : 1; i < len(prices); i{val0…...

SQLserver基础入门理论(超基础)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️努力不一定有回报&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xf…...

(三)行为模式:7、观察者模式(Observer Pattern)(C++示例)

目录 1、观察者模式&#xff08;Observer Pattern&#xff09;含义 2、观察者模式的UML图学习 3、观察者模式的应用场景 4、观察者模式的优缺点 &#xff08;1&#xff09;优点&#xff1a; &#xff08;2&#xff09;缺点 5、C实现观察者模式的实例 1、观察者模式&…...

2019CVPR Semantic Graph Convolutional Networks for 3D Human Pose Regression

基于语义图卷积网络的三维人体姿态回归 源码 https://github.com/garyzhao/SemGCN 摘要 在本文中&#xff0c;我们研究了学习图卷积网络&#xff08;GCN&#xff09;回归的问题。GCN的当前体系结构受限于卷积滤波器和共享的变换矩阵为的小感受野。为了解决这些限制&#xff…...

大数据课程K16——Spark的梯度下降法

文章作者邮箱&#xff1a;yugongshiyesina.cn 地址&#xff1a;广东惠州 ▲ 本章节目的 ⚪ 了解Spark的梯度下降法&#xff1b; ⚪ 了解Spark的梯度下降法家族&#xff08;BGD&#xff0c;SGD&#xff0c;MBGD&#xff09;&#xff1b; ⚪ 掌握Spark的MLlib实现…...

springboot:时间格式化的5种方法(解决后端传给前端的时间格式转换问题)推荐使用第4和第5种!

本文转载自&#xff1a;springboot&#xff1a;时间格式化的5种方法&#xff08;解决后端传给前端的时间显示不一致&#xff09;_为什么前端格式化日期了后端还要格式化_洛泞的博客-CSDN博客 时间问题演示 为了方便演示&#xff0c;我写了一个简单 Spring Boot 项目&#xff…...

六、vim编辑器的使用

1、编辑器 (1)编辑器就是一款软件。 (2)作用就是用来编辑文件&#xff0c;譬如编辑文字、编写代码。 (3)Windows中常用的编辑器&#xff0c;有自带的有记事本(notepad)&#xff0c;比较好用的notepad、VSCode等。 (4)Linux中常用的编辑器&#xff0c;自带的最古老的vi&…...

【易售小程序项目】项目介绍与系列文章集合

项目介绍 易售二手小程序主要用于校园中二手商品的交易&#xff0c;该系列文章会记录这个小程序前端的整个开发过程并提供详细代码&#xff0c;后台主要基于若依管理系统搭建&#xff0c;文章中也会提及后端关键部分的实现及代码。希望该系列文章可以帮助小白了解项目的开发流…...

游戏服务器成DDoS最大攻击重灾区

游戏产业的迅猛发展也让游戏产业成为被黑客攻击的重灾区。什么原因让游戏行业成为DDoS的攻击重点。总结有如下原因和主要手段&#xff1a; 1.游戏行业的攻击成本较低&#xff0c;攻防成本1&#xff1a;N。随着DDoS攻击的打法越来越复杂&#xff0c;攻击点更是越来越多&#xff…...

[SpringBoot3]博客管理系统(源码放评论区了)

八、博客管理系统 创建新的SpringBoot项目&#xff0c;综合运用以上知识点&#xff0c;做一个文章管理的后台应用。依赖&#xff1a; Spring WebLombokThymeleafMyBatis FrameworkMySQL DriverBean Validationhutool 需求&#xff1a;文章管理工作&#xff0c;发布新文章&…...

C语言——指针基本语法

概述 内存地址 在计算机内存中&#xff0c;每个存储单元都有一个唯一的地址(内存编号)。 通俗理解&#xff0c;内存就是房间&#xff0c;地址就是门牌号 指针和指针变量 指针&#xff08;Pointer&#xff09;是一种特殊的变量类型&#xff0c;它用于存储内存地址。 指针的实…...

elementui table 在浏览器分辨率变化的时候界面异常

异常点&#xff1a; 界面显示不完整&#xff0c;表格卡顿&#xff0c;界面已经刷新完成&#xff0c;但是表格的宽度还在一点一点变化&#xff0c;甚至有无线延伸的情况 思路&#xff1a; 1. 使用doLayout 这里官方文档有说明&#xff0c; 所以我的想法是&#xff0c;监听浏览…...

六、Kafka-Eagle监控

目录 6.1 MySQL 环境准备6.2 Kafka 环境准备6.3 Kafka-Eagle 安装 6.1 MySQL 环境准备 Kafka-Eagle 的安装依赖于 MySQL&#xff0c;MySQL 主要用来存储可视化展示的数据 6.2 Kafka 环境准备 修改/opt/module/kafka/bin/kafka-server-start.sh 命令 vim bin/kafka-server-sta…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例

目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码&#xff1a;冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...

数据库正常,但后端收不到数据原因及解决

从代码和日志来看&#xff0c;后端SQL查询确实返回了数据&#xff0c;但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离&#xff0c;并且ai辅助开发的时候&#xff0c;很容易出现前后端变量名不一致情况&#xff0c;还不报错&#xff0c;只是单…...

生产管理系统开发:专业软件开发公司的实践与思考

生产管理系统开发的关键点 在当前制造业智能化升级的转型背景下&#xff0c;生产管理系统开发正逐步成为企业优化生产流程的重要技术手段。不同行业、不同规模的企业在推进生产管理数字化转型过程中&#xff0c;面临的挑战存在显著差异。本文结合具体实践案例&#xff0c;分析…...