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

【Mybatis 与 Spring】事务相关汇总

之前分享的几篇文章可以一起看,形成一个体系

【Mybatis】一级缓存与二级缓存源码分析与自定义二级缓存
【Spring】Spring事务相关源码分析
【Mybatis】Mybatis数据源与事务源码分析

Spring与Mybaitis融合

SpringManagedTransaction:

org.mybatis.spring.transaction.SpringManagedTransaction :mybatis处理事务的类,打通了 MyBatis 的事物管理、连接管理 和 spring-tx 的 事物管理、连接管理,使得 MyBatis 与 Spring 可以使用统一的方式来管理连接的生命周期 和 事务处理。
org.mybatis.spring.transaction.SpringManagedTransactionFactory:创建SpringManagedTransaction

SqlSession:

org.apache.ibatis.session.SqlSession
->
org.mybatis.spring.SqlSessionTemplate:mybatis与spring整合后执行sql时使用的就是这个实现,它是通过内部持有的SqlSession代理对象来执行sql
->
org.apache.ibatis.session.SqlSessionFactory->DefaultSqlSessionFactory:创建SqlSession(DefaultSqlSession)

TransactionSynchronizationManager:

TransactionSynchronizationManager:事务同步器,会将连接资源绑定到 ThreadLocal 变量中,如果是在同一个事务当中的话,就可以通过 TransactionSynchronizationManager 中的 ThreadLocal 变量来获取到同一个连接资源。

  • mybatis-spring.jar 是通过 SqlSessionTemplate 来创建 SqlSession 的代理 sqlSessionProxy;
  • sqlSessionProxy 会通过 SqlSessionInterceptor 来对 SqlSession 中的每个 sql 操作进行拦截,从而使用 spring-tx 的事务同步器 TransactionSynchronizationManager 中管理的 SqlSession 来执行 sql。
  • 在执行 sql 前,是通过 SpringManagedTransaction 来获取连接和管理事物的。
  • 如果是 @Transactional 标记的事物方法,SpringManagedTransaction 就会放弃事物的管理,交由 spring-tx 的 TransactionInterceptor 来进行 aop 拦截,从而管理事物。

MyBatis 原生的 连接管理 和 事物管理:

MyBatis 原生的 连接管理 和 事物管理 是交给 org.apache.ibatis.transaction.Transaction 来管理的。
Spring-tx 主要封装的是事物管理,事物管理操作是通过 DataSourceTransactionManager 来实现的。而连接的管理是通过 org.springframework.jdbc.datasource.DataSourceUtils 来操作具体的 DataSource 来实现的。
在这里插入图片描述
在这里插入图片描述

MyBatis 与 Spring-tx 的事物管理的整合

MyBatis 与 Spring-tx 的事物管理的整合是通过 mybatis-spring-.jar 中的 SpringManagedTransaction 来完成的。
SpringManagedTransaction 打通了 MyBatis 的事物管理、连接管理 和 spring-tx 的 事物管理、连接管理,使得 MyBatis 与 Spring 可以使用统一的方式来管理连接的生命周期 和 事务处理。
在这里插入图片描述
MyBatis 与 Spring 结合之后,sql 的执行具体会通过实现类 org.mybatis.spring.SqlSessionTemplate 来完成。
SqlSessionTemplate 每次在执行 sql 时,都会被 SqlSessionInterceptor 进行拦截,拦截后会通过 Spring 的事务同步器 TransactionSynchronizationManager 获取到当前的 SqlSession 去执行 sql 操作。
SqlSessionInterceptor 保证了 MyBatis 的 SqlSession 在执行 sql 时使用的连接与 Spring 事物管理操作使用的连接是同一个连接。

TransactionSynchronizationManager

作用:

TransactionSynchronizationManager是事务同步管理器。 管理每个线程的资源和事务同步。

在原生JDBC中我们获取连接的connection 是非线程安全的,因为每一个数据库操作都要获取一个connection对象。不能只创建一次,共享connection。否则会出现数据不一致的情况。

所以connection本身是线程不安全的,并且connection创建开销比较大,所以一般使用数据库连接池来统一的管理connection对象,例如druid连接池、c3p0连接池、连接池等。

spring帮我管理事务的情况下,在使用事务的情况下 ,实际上是在ConnectionHolder中获取的Connection。而ConnectionHolder是在TransactionSynchronizationManager中获取的resources属性的值,即connection对象信息。

重点源码

现在我们看着这里衔接这整个事务去操作数据源的数据。

下面就是我们熟悉的,通过下面,我们可以使用当前的类,去拿到我们去操作数据的链接或者SqlSession

  • 数据源-》ConnectionHolder
  • SqlSessionFactory-》SqlSessionHolder
  • 在这里插入图片描述
    那这两个是什么时候放进去的呢?

1.第一个是在执行insert之前,放进去的

org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin

在这里插入图片描述
在这里插入图片描述
2.第二个是在执行insert的时候放进去,以便后面使用的

SqlSessionUtils

org.mybatis.spring.SqlSessionUtils#getSqlSession(org.apache.ibatis.session.SqlSessionFactory, org.apache.ibatis.session.ExecutorType, org.springframework.dao.support.PersistenceExceptionTranslator)

第一次获取的时候还为null,所以拿不到SqlSessionHolder

在这里插入图片描述
放置是在下面进行的

org.mybatis.spring.SqlSessionUtils#registerSessionHolder

在这里插入图片描述
放进去了
在这里插入图片描述
这时候 事务同步管理器就保存上了当前线程的数据源和执行所需要的sqlsession类等信息了。

后面很多地方都可以通过下面的代码获取到我们的ConnectionHolder和 SqlSessionHolder。

  • ConnectionHolder、SqlSessionHolder 的工作机制是:我们将Connection对象放在一个全局公用的地方,然后在不同的操作中都从这个地方取得Connection,从而完成Connection共享的目的,但是要记住 在当前线程完成之后会把 此对象销毁掉
ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);

总结:

commit执行流程

准备事务

com.qax.ztb.machine.facade.TestController#commitTest
->
org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept:Cglib中方法用于方法拦截的Interceptor拦截器
->
org.springframework.aop.framework.ReflectiveMethodInvocation#ReflectiveMethodInvocation:Cglib代理涉及的CallbackDynamicAdvisedInterceptor织入增强流程,初始化ReflectiveMethodInvocation。并且植入 TransactionInterceptor
-> 
org.springframework.aop.framework.ReflectiveMethodInvocation#proceed :回调此方法,通过TransactionInterceptor去反射调用invoke
->
org.springframework.transaction.interceptor.TransactionInterceptor#invoke :执行事务植入
->
org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction:实际植入事务方法
->
org.springframework.transaction.interceptor.TransactionAspectSupport#createTransactionIfNecessary:创建TransactionInfo事务信息类-->  org.springframework.transaction.PlatformTransactionManager#getTransaction:创建 TransactionStatus  -->  org.springframework.transaction.support.AbstractPlatformTransactionManager#startTransaction:实际创建           TransactionStatus类方法-->org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin:给                      DataSourceTransactionObject 进行事务参数配置,并且绑定DataSourceConnectionHolderThreadLocal-->org.springframework.transaction.support.AbstractPlatformTransactionManager#prepareSynchronization:初始化     TransactionSynchronizationManager其他事务参数,均绑定到  ThreadLocal-->org.springframework.transaction.interceptor.TransactionAspectSupport#prepareTransactionInfo:TransactionInfo注入新的属性准备完成此类
-> org.springframework.transaction.interceptor.TransactionAspectSupport.CoroutinesInvocationCallback#proceedWithInvocation:回调
->
actionLogMapper.insert:开始执行我们的新增操作  

执行操作,提交事务

actionLogMapper.insert(actionLogEntity);
->
com.baomidou.mybatisplus.core.override.MybatisMapperProxy#invoke:在项目启动中,已经把每一个Mapper都设置了MybatisMapperProxy的代理,所以具体执行的话,就要走invoke方法去执行具体操作。注意:这个时候sqlSession也已经在初始化中准备好了。-->com.baomidou.mybatisplus.core.override.MybatisMapperProxy.PlainMethodInvoker#invoke:然后通过 MybatisMapperMethod的invoke方法去调用具体的执行逻辑。注意sqlSession等于SqlSessionTemplate。在构建SqlSessionTemplate的时候,已经通过反射把sqlSessionProxy创建完成并且植入了SqlSessionInterceptor,所以调用SqlSessionTemplate的方法,会被拦截。
->  
org.mybatis.spring.SqlSessionTemplate.SqlSessionInterceptor#invoke:拦截调用,获取SqlSession,进行commit-->org.springframework.transaction.support.TransactionSynchronizationManager#getResource:这个时候会获取数据库连接 -->org.springframework.transaction.support.TransactionSynchronizationManager#getResource:通过key(DataSoure)获取到我们前面创建的 ConnectionHolder,在里面就可以获得我们设置的DataSoure了--> 之后就直接调用操作数据库即可。  ->
org.springframework.transaction.interceptor.TransactionAspectSupport#commitTransactionAfterReturning:回调此方法进行实际的事务提交操作-->org.springframework.transaction.support.AbstractPlatformTransactionManager#commitorg.springframework.transaction.support.AbstractPlatformTransactionManager#processCommit-->org.springframework.jdbc.datasource.DataSourceTransactionManager#doCommit:最终在这里提交:通过DataSourceTransactionObject,得到ConnectionHolder中的Connection,进行commit
->
最后清理,结束。   

相关文章:

【Mybatis 与 Spring】事务相关汇总

之前分享的几篇文章可以一起看,形成一个体系 【Mybatis】一级缓存与二级缓存源码分析与自定义二级缓存 【Spring】Spring事务相关源码分析 【Mybatis】Mybatis数据源与事务源码分析 Spring与Mybaitis融合 SpringManagedTransaction: org.mybatis.spri…...

Leetcode 2065. 最大化一张图中的路径价值(DFS / 最短路)

Leetcode 2065. 最大化一张图中的路径价值 暴力DFS 容易想到,从0点出发DFS,期间维护已经走过的距离(时间)和途径点的权值之和,若访问到0点则更新答案,若下一步的距离与已走过的距离和超出了maxTime&#…...

SeeSR: Towards Semantics-Aware Real-World Image Super-Resolution

CVPR2024 香港理工大学&OPPO&bytedancehttps://github.com/cswry/SeeSR?tabreadme-ov-file#-licensehttps://arxiv.org/pdf/2311.16518#page5.80 问题引入 因为有些LR退化情况比较严重,所以超分之后的结果会出现语义的不一致的情况,所以本文训…...

七月论文审稿GPT第5版:拿我司七月的早期paper-7方面review数据集微调LLama 3

前言 llama 3出来后,为了通过paper-review的数据集微调3,有以下各种方式 不用任何框架 工具 技术,直接微调原生的llama 3,毕竟也有8k长度了 效果不期望有多高,纯作为baseline通过PI,把llama 3的8K长度扩展…...

盘古5.0,靠什么去解最难的题?

文|周效敬 编|王一粟 当大模型的竞争开始拼落地,商业化在B端和C端都展开了自由生长。 在B端,借助云计算向千行万业扎根;在C端,通过软件App和智能终端快速迭代。 在华为,这家曾经以通信行业起…...

2.3章节Python中的数值类型

1.整型数值 2.浮点型数值 3.复数   Python中的数值类型清晰且丰富,主要分为以下几种类型,每种类型都有其特定的用途和特性。 一、整型数值 1.定义:整数类型用于表示整数值,如1、-5、100等。 2.特点: Python 3中的…...

每日Attention学习7——Frequency-Perception Module

模块出处 [link] [code] [ACM MM 23] Frequency Perception Network for Camouflaged Object Detection 模块名称 Frequency-Perception Module (FPM) 模块作用 获取频域信息,更好识别伪装对象 模块结构 模块代码 import torch import torch.nn as nn import to…...

【从0实现React18】 (五) 初探react mount流程 完成核心递归流程

更新流程的目的: 生成wip fiberNode树标记副作用flags 更新流程的步骤: 递:beginWork归:completeWork 在 上一节 ,我们探讨了 React 应用在首次渲染或后续更新时的整体更新流程。在 Reconciler 工作流程中&#xff…...

0-30 VDC 稳压电源,电流控制 0.002-3 A

怎么运行的 首先,有一个次级绕组额定值为 24 V/3 A 的降压电源变压器,连接在电路输入点的引脚 1 和 2 上。(电源输出的质量将直接影响与变压器的质量成正比)。变压器次级绕组的交流电压经四个二极管D1-D4组成的电桥整流。桥输出端…...

HTML5+CSS3+JS小实例:图片九宫格

实例:图片九宫格 技术栈:HTML+CSS+JS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1…...

湘潭大学软件工程数据库总结

文章目录 前言试卷结构给学弟学妹的一些参考自己的一些总结 前言 自己可能很早很早之前就准备复习了&#xff0c;但是感觉还是没有学到要点&#xff0c;主要还是没啥紧迫的压力&#xff0c;我们是三月份开学&#xff0c;那时候实验室有朋友挺认真开始学习数据库了&#xff0c;…...

Codeforces Testing Round 1 B. Right Triangles 题解 组合数学

Right Triangles 题目描述 You are given a n m nm nm field consisting only of periods (‘.’) and asterisks (‘*’). Your task is to count all right triangles with two sides parallel to the square sides, whose vertices are in the centers of ‘*’-cells. …...

怎样将word默认Microsoft Office,而不是WPS

设置——>应用——>默认应用——>选择"word"——>将doc和docx都选择Microsoft Word即可...

C语言之进程的学习2

Env环境变量&#xff08;操作系统的全局变量&#xff09;...

web使用cordova打包Andriod

一.安装Gradel 1.下载地址 Gradle Distributions 2.配置环境 3.测试是否安装成功 在cmd gradle -v 二.创建vite项目 npm init vitelatest npm install vite build 三.创建cordova项目 1.全局安装cordova npm install -g cordova 2. 创建项目 cordova create cordova-app c…...

内卷情况下,工程师也应该了解的项目管理

简介&#xff1a;大家好&#xff0c;我是程序员枫哥&#xff0c;&#x1f31f;一线互联网的IT民工、&#x1f4dd;资深面试官、&#x1f339;Java跳槽网创始人。拥有多年一线研发经验&#xff0c;曾就职过科大讯飞、美团网、平安等公司。在上海有自己小伙伴组建的副业团队&…...

【解锁未来:深入了解机器学习的核心技术与实际应用】

解锁未来&#xff1a;深入了解机器学习的核心技术与实际应用 &#x1f48e;1.引言&#x1f48e;1.1 什么是机器学习&#xff1f; &#x1f48e;2 机器学习的分类&#x1f48e;3 常用的机器学习算法&#x1f48e;3.1 线性回归&#xff08;Linear Regression&#xff09;&#x1…...

1-3.文本数据建模流程范例

文章最前&#xff1a; 我是Octopus&#xff0c;这个名字来源于我的中文名–章鱼&#xff1b;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github &#xff1b;这博客是记录我学习的点点滴滴&#xff0c;如果您对 Python、Java、AI、算法有兴趣&#xff0c;可以关注我的…...

【FFmpeg】avformat_alloc_output_context2函数

【FFmpeg】avformat_alloc_output_context2函数 1.avformat_alloc_output_context21.1 初始化AVFormatContext&#xff08;avformat_alloc_context&#xff09;1.2 格式猜测&#xff08;av_guess_format&#xff09;1.2.1 遍历可用的fmt&#xff08;av_muxer_iterate&#xff0…...

Flask 缓存和信号

Flask-Caching Flask-Caching 是 Flask 的一个扩展&#xff0c;它为 Flask 应用提供了缓存支持。缓存是一种优化技术&#xff0c;可以存储那些费时且不经常改变的运算结果&#xff0c;从而加快应用的响应速度。 一、初始化配置 安装 Flask-Caching 扩展&#xff1a; pip3 i…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...