【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代理涉及的Callback之DynamicAdvisedInterceptor织入增强流程,初始化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 进行事务参数配置,并且绑定DataSource和ConnectionHolder到ThreadLocal-->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 工作流程中ÿ…...
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…...
湘潭大学软件工程数据库总结
文章目录 前言试卷结构给学弟学妹的一些参考自己的一些总结 前言 自己可能很早很早之前就准备复习了,但是感觉还是没有学到要点,主要还是没啥紧迫的压力,我们是三月份开学,那时候实验室有朋友挺认真开始学习数据库了,…...
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环境变量(操作系统的全局变量)...
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…...
内卷情况下,工程师也应该了解的项目管理
简介:大家好,我是程序员枫哥,🌟一线互联网的IT民工、📝资深面试官、🌹Java跳槽网创始人。拥有多年一线研发经验,曾就职过科大讯飞、美团网、平安等公司。在上海有自己小伙伴组建的副业团队&…...
【解锁未来:深入了解机器学习的核心技术与实际应用】
解锁未来:深入了解机器学习的核心技术与实际应用 💎1.引言💎1.1 什么是机器学习? 💎2 机器学习的分类💎3 常用的机器学习算法💎3.1 线性回归(Linear Regression)…...
1-3.文本数据建模流程范例
文章最前: 我是Octopus,这个名字来源于我的中文名–章鱼;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github ;这博客是记录我学习的点点滴滴,如果您对 Python、Java、AI、算法有兴趣,可以关注我的…...
【FFmpeg】avformat_alloc_output_context2函数
【FFmpeg】avformat_alloc_output_context2函数 1.avformat_alloc_output_context21.1 初始化AVFormatContext(avformat_alloc_context)1.2 格式猜测(av_guess_format)1.2.1 遍历可用的fmt(av_muxer_iterate࿰…...
Flask 缓存和信号
Flask-Caching Flask-Caching 是 Flask 的一个扩展,它为 Flask 应用提供了缓存支持。缓存是一种优化技术,可以存储那些费时且不经常改变的运算结果,从而加快应用的响应速度。 一、初始化配置 安装 Flask-Caching 扩展: pip3 i…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...
