spring事务管理器原理?mybatis如何集成spring事务管理器?

news2024/11/29 2:41:02

目录

1. spring事务管理器开启事务做了些什么事情:

1.1 创建mysql数据库连接:

1.2 开启mysql事务

1.3 将当前事务所使用的连接绑定到ThreadLocal中,供后续执行sql命令使用。

2. mybatis如何集成spring事务管理器?

3. mysql相关命令

4. 一个方便调试的数据库Datasource

5. 参考文档:


1. spring事务管理器开启事务做了些什么事情:

首先是如何开启事务:
a代码方式:直接调用org.springframework.jdbc.datasource.DataSourceTransactionManager的
b注解方式:@Transaction
这两种方式最终都是调用如下接口的三个方法来实现创建事务,执行commit,执行rollback动作的。

org.springframework.transaction.PlatformTransactionManager#getTransaction

要理解spring事务的原理,重点就是要了解创建事务(getTransaction方法),究竟做了些什么事情。其中@Transaction方式事务,是在AOP代理的拦截方法中执行的创建事务(@Transaction注解method之前创建事务)。

getTransaction方法主要做了以下三件事情:


1.1 创建mysql数据库连接:

因此在进入@Transaction注解method之前就已经创建了数据库连接。

@Transaction进入/出method就创建/关闭数据库连接。

因此@Transaction注解,不能包含太大的方法。包含太大的逻辑,就会导致数据库连接占用时间过长。

1.2 开启mysql事务


执行命令:SET autocommit=0

1.3 将当前事务所使用的连接绑定到ThreadLocal中,供后续执行sql命令使用。

最终存储ThreadLocal为:org.springframework.transaction.support.TransactionSynchronizationManager#resources

// org.springframework.transaction.support.TransactionSynchronizationManager

public abstract class TransactionSynchronizationManager {
   // 事务管理器创建的连接,存储位置
   private static final ThreadLocal<Map<Object, Object>> resources =
         new NamedThreadLocal<>("Transactional resources");

# org.springframework.jdbc.datasource.DataSourceTransactionManager
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
   DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
   Connection con = null;

   try {
      if (!txObject.hasConnectionHolder() ||
            txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
         //1.1 创建mysql数据库连接:
         Connection newCon = obtainDataSource().getConnection();  
         if (logger.isDebugEnabled()) {
            logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
         }
         txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
      }
      
      // 省略部分代码。。。
     	if (con.getAutoCommit()) {
				txObject.setMustRestoreAutoCommit(true);
				if (logger.isDebugEnabled()) {
					logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
				}
                1.2 开启mysql事务,执行命令:SET autocommit=0
				con.setAutoCommit(false);
			}
			// 省略部分代码。。。
      // Bind the connection holder to the thread.
      if (txObject.isNewConnectionHolder()) {
         1.3 将当前事务所使用的连接绑定到ThreadLocal中,供后续执行sql命令使用。
         TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
      }
   }
   // 省略部分代码。。。
}

2. mybatis如何集成spring事务管理器?

mybatis执行sql会调用 SqlSessionTemplate获取连接,然后会调用
org.mybatis.spring.SqlSessionUtils#getSqlSession(org.apache.ibatis.session.SqlSessionFactory, org.apache.ibatis.session.ExecutorType, org.springframework.dao.support.PersistenceExceptionTranslator)
方法,这个方法首先会检查事务管理的ThreadLocal中是否已经有了数据库连接,有的话,就直接用此数据库连接(这样就实现了和spring事务管理器的集成,共用数据库连接);如果没有,那么就重新创建一个连接。

因此mybatis不需要做什么配置就可以和spring事务管理器进行自动集成(ThreadLocal是二者集成的纽带),只需要二者使用相同DataSource即可。

# org.mybatis.spring.SqlSessionUtils
public static SqlSession getSqlSession(SqlSessionFactory sessionFactory, ExecutorType executorType,
    PersistenceExceptionTranslator exceptionTranslator) {

  notNull(sessionFactory, NO_SQL_SESSION_FACTORY_SPECIFIED);
  notNull(executorType, NO_EXECUTOR_TYPE_SPECIFIED);
  
  // 从事务管理器ThreadLocal中获取连接
  SqlSessionHolder holder = (SqlSessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);

  SqlSession session = sessionHolder(executorType, holder);
  if (session != null) {
    return session;
  }

  // 没有获取到连接,就重新创建连接
  LOGGER.debug(() -> "Creating a new SqlSession");
  session = sessionFactory.openSession(executorType);

  registerSessionHolder(sessionFactory, executorType, exceptionTranslator, session);

  return session;
}

3. mysql相关命令

查看mysql服务器存在的客户端连接:SELECT * FROM information_schema.PROCESSLIST;

查看mysql所执行的命令(包括查询命令):

show variables where Variable_name="general_log";

set global general_log=on;

show variables where Variable_name="general_log_file";

4. 一个方便调试的数据库Datasource

org.springframework.jdbc.datasource.DriverManagerDataSource

每次获取连接都是通过驱动真实的和mysql服务器创建连接。每次释放连接都是真实的通过驱动和mysql服务解除连接。
 

5. 参考文档:

详解 Spring 注解@Transactional事务控制原理

springboot开启声明式事务 - 腾讯云开发者社区-腾讯云

mysql中set autocommit=0与start transaction区别_yygr的博客-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java常用框架(三)

三、SpringBoot 1.Spring及其优缺点&#xff1f; 1.1 概念 重量级企业开发框架EJB的替代品&#xff0c;通过依赖注入、面向切面编程&#xff0c;使用简单Java对象POJO为企业Java开发提供了相对简单的方法。 1.2 优缺点 1.2.1 优点 组件代码轻量级 1.2.1 缺点 配置重量级…

Spring Batch 高级篇-多线程步骤

目录 引言 概念 案例 转视频版 引言 接着上篇&#xff1a;Spring Batch ItemWriter组件&#xff0c;了解Spring Batch ItemWriter处理组件后&#xff0c;接下来一起学习一下Spring Batch 高级功能-多线程步骤 概念 默认的情况下&#xff0c;步骤基本上在单线程中执行&…

springBoot使用ShardingJDBC实现分表

ShardingSphere的介绍 ShardingSphere是一款起源于当当网内部的应用框架。2015年在当当网内部诞 生&#xff0c;最初就叫ShardingJDBC。2016年的时候&#xff0c;由其中一个主要的开发人员张亮&#xff0c; 带入到京东数科&#xff0c;组件团队继续开发。在国内历经了当当网、…

链动2+1系统|购买三单就能迅速回本,链动2+1模式到底有多暴利?

链动21模式号称起步创业无泡沫&#xff0c;半个月就能盈利上百万&#xff0c;用户裂变速度更是让人瞠目结舌。那么&#xff0c;链动21模式到底有多暴利&#xff1f;其实链动21模式最关键的&#xff0c;是合理的利润分配和奖励机制&#xff0c;让消费者在购物的同时&#xff0c;…

【解决报错】‘jupyter‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件

在当前路径下使用cmd打开后&#xff0c;输入jupyter notebook出现如下错误&#xff1a; 通常可能出现的问题有两种&#xff1a; &#xff08;1&#xff09;你本身就没安装jupyter&#xff0c;如果你配置了anaconda&#xff0c;就自带jupyter&#xff0c;直接跳到问题2。如果确…

Confluence主页面更新记录停留在去年,搜索也只能搜索去年之前的数据问题解决方案

问题描述 Confluence主页最近更新页面不更新了&#xff0c;停留在之前的时间段。其次搜索也只能搜索出来停留在这个时间段之前的数据。 核心原因 索引出现问题了&#xff0c;重建索引即可。 解决办法 直接重启Confluence。 重启Confluence的姿势 描述一下我解决思路&…

28-vuex

vuex 一、vuex 专门在vue中实现集中式状态&#xff08;数据&#xff09;管理的一个Vue插件&#xff0c;对Vue应用中多个组件的共享状态进行集中式的管理&#xff08;读/写&#xff09;&#xff0c;也是一种组件间通信的方式&#xff0c;且适用于任意组件间通信。 使用场景&a…

Java 【数据结构OJ题十道】—— 二叉树篇1

文章目录一、 检查两棵二叉树是否相同二、 另一棵二叉树的子树三、 二叉树的构建及遍历四、序列化二叉树和反序列化二叉树(难)五、二叉树创建字符串六、 二叉树前序非递归遍历实现七、 二叉树中序非递归遍历实现八、 二叉树后序非递归遍历实现九、二叉搜索树中找到两个结点的最…

如何将电脑文件备份到百度网盘

如何将电脑文件备份到百度网盘&#xff1f;说到文件备份&#xff0c;很多小伙伴会将电脑文件备份到移动硬盘或者U盘里&#xff0c;移动硬盘和U盘是比较常见的存储介质&#xff0c;使用和携带起来也是非常方便&#xff0c;因此深受大家的喜欢。除此之外&#xff0c;大家可能还忽…

2023年,IT互联网还有发展前景吗?

不得不说&#xff0c;互联网在整个社会经济发展中扮演着不可或缺的角色&#xff1b;不仅自身的技术具有前沿性&#xff0c;也推动着其他行业进入数字化经济时代&#xff0c;让我们的工作生活变得更加便捷。 在“互联网”时代&#xff0c;每个服务行业都会利用大数据&#xff0…

将自带记事本替换为Notepad2【中文版,带替换文件】

Notepad2是我在寻找一个合适的代码浏览工具的时候发现的&#xff0c;当需要一个用来浏览代码的文本编辑器时候&#xff0c;需要体积小&#xff0c;速度快&#xff0c;语法高亮&#xff0c;解释度高&#xff0c;VsCode作为生产环境已经不适合作为浏览工具了。了解到Notepad2&…

《动手学习深度学习》笔记(二)线性神经网络

三、线性神经网络 3.1 线性回归 3.1.1 介绍 1. 回归是为一个或多个自变量与因变量之间的关系建模的一类方法。而线性回归基于几个简单的假设&#xff1a;① 自变量和因变量关系是线性的&#xff1b;② 允许包含噪声但是噪声遵循正态分布。   2. 训练数据集/训练集&#xff…

算法训练营 day53 动态规划 买卖股票的最佳时机系列2

算法训练营 day53 动态规划 买卖股票的最佳时机系列2 买卖股票的最佳时机III 123. 买卖股票的最佳时机 III - 力扣&#xff08;LeetCode&#xff09; 给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。…

软件项目管理知识回顾---网络图

网络图 9.网络图 9.1简介 1.分类 AOA&#xff0c;双代号&#xff0c;ADMAON,PDM&#xff0c;单代号&#xff0c;前导图2.活动的逻辑管理 头到头/尾&#xff0c;尾到头/尾 依赖关系 3.工序 紧前紧后9.2绘制规则 1.两个节点只能一条线。不能是平行线。平行的话就不知道是哪个活动…

LeetCode-93. 复原 IP 地址

目录题目思路回溯法题目来源 93. 复原 IP 地址 题目思路 意识到这是切割问题&#xff0c;切割问题就可以使用回溯搜索法把所有可能性搜出来&#xff0c;和131.分割回文串就十分类似了。 回溯法 1.递归参数 startIndex一定是需要的&#xff0c;因为不能重复分割&#xff0c…

【GeoDjango框架解析】读取矢量数据写入postgis数据库

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 【GeoDjango框架解析】读取矢量数据写入postgis数据库 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录系列…

关于iframe一些通讯的记录(可适用工作流审批,文中有项目实践,欢迎咨询)

一.知识点(1).我们可以通过postMessage(发送方)和onmessage(接收方)这两个HTML5的方法, 来解决跨页面通信问题&#xff0c;或者通过iframe嵌套的不同页面之间的通信a.父页面代码如下<div v-if"src" class"iframe"><iframeref"iframe"id…

Kafka进阶篇-消费者详解Flume消费Kafka原理

简介 由于挺多时候如果不太熟系kafka消费者详细的话&#xff0c;很容易产生问题&#xff0c;所有剖析一定的原理很重要。 Kafka消费者图解 消费方式 消费者总体工作流程 消费者组初始化流程 消费者详细消费流程 消费者重要参数 bootstrap.servers 向 Kafka 集群建立初…

Jackson使用进阶

实现 注解 属性命名 JsonProperty 定义属性序列化时的名称。 JacksonAnnotation public interface JsonProperty {public final static String USE_DEFAULT_NAME "";public final static int INDEX_UNKNOWN -1;//指定属性的名称。String value() default USE_…

2022IDEA搭建springMvc项目

springmvc项目搭建一. 创建maven项目二. Add Framework Support三. 添加依赖并配置maven四. 配置前端控制器DispatcherServlet五. 配置SpringMVC.XML文件六. 创建controller类七. 创建index.html页面八. 查看jar包是否添加九. 配置tomcat&#xff08;重&#xff09;十. springm…