【老王读Spring Transaction-6】spring-tx与DataSource连接池整合的原理

news2024/10/2 22:26:49

06spring-tx与DataSource连接池的原理

  • 前言
  • Spring 版本
  • 正文
    • 事物连接: Spring-managed transactional Connections
    • spring-tx 与 DataSource 的整合
      • SpringBoot 默认使用的 DataSource 连接池是 Hikari
    • 事物连接的关闭/释放: 并不是真正的关闭
  • 小结

前言

javax.sql.DataSource 是 java 提供的一个获取 DB 连接的标准接口。
它的实现类可以通过简单的实现,生成标准的连接对象;也可以使用连接池方式实现,生成的池化的连接对象。

通常在企业级的开发当中,我们都会使用池化的连接对象,比如使用 apache 的 DBCP 连接池、阿里的 druid 连接池、springboot 默认使用的 hikari 连接池等

那么,DataSource 是如何与 spring-tx 进行结合的呢?

spring-tx 的核心关注点是事务的管理。连接的获取和关闭是交给连接池去实现的。
其实, spring-tx 管理的是 事物连接。(后续会细说)

public interface DataSource  extends CommonDataSource, Wrapper {

  /**
   * 尝试与此 DataSource 对象表示的数据源建立连接
   */
  Connection getConnection() throws SQLException;
  
  Connection getConnection(String username, String password) throws SQLException;
}

Spring 版本

spring-tx 5.3.9 (通过 SpringBoot 2.5.3 间接引入的依赖)

正文

spring-tx 中获取事物连接是通过 DataSourceTransactionManager#doGetTransaction() 来获取的:

// org.springframework.jdbc.datasource.DataSourceTransactionManager
protected Object doGetTransaction() {
    DataSourceTransactionObject txObject = new DataSourceTransactionObject();
    txObject.setSavepointAllowed(isNestedTransactionAllowed());
    ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
    txObject.setConnectionHolder(conHolder, false);
    return txObject;
}

protected DataSource obtainDataSource() {
    DataSource dataSource = getDataSource();
    Assert.state(dataSource != null, "No DataSource set");
    return dataSource;
}

获取连接最终会委托到 DataSourceUtils#doGetConnection() 来获取。

org.springframework.jdbc.datasource.DataSourceUtils:
DataSourceUtils 是通过静态方法,从指定的 DataSource 获取 JDBC 连接的 helper 类。
它里面包含了对 spring 管理的事物连接的特殊支持。(通常是指被 DataSourceTransactionManager 管理的事务连接)。

事物连接: Spring-managed transactional Connections

DataSourceUtils 的源码注释中有一段话:
Helper class that provides static methods for obtaining JDBC Connections from a DataSource. Includes special support for Spring-managed transactional Connections, e.g. managed by DataSourceTransactionManager or org.springframework.transaction.jta.JtaTransactionManager.

里面提到了 Spring-managed transactional Connections这里要强调一下: JDBC ConnectionSpring-managed transactional Connections 是有区别的。
通常所说的 JDBC Connection 是普通的 jdbc 连接。而 Spring-managed transactional Connections 是受 Spring 管理的事物连接(通常 @Transactional 标记的事物方法使用的就是 Spring 管理的事物连接)。
可以通过 DataSourceUtils#isConnectionTransactional(Connection con, DataSource dataSource) 方法去判断一个 jdbc 连接是否是一个 Spring 管理的事物连接。
而非事物连接通常也是从 DataSource 中获取的,只是这些非事物连接不是被事物管理器 DataSourceTransactionManager 来管理的。

DataSourceTransactionManager 的类图如下:
TransactionManager.png

spring-tx 与 DataSource 的整合

TransactionManager 自动配置的源码:
DataSourceTransactionManagerAutoConfiguration.png

可以看到,TransactionManager 这个 bean 的创建依赖 DataSource 这个 bean。这样,Spring 管理的 DataSource 就与 spring-tx 整合在一起了。
连接的获取就是通过 Spring 管理的 DataSource 来获取的。

SpringBoot 默认使用的 DataSource 连接池是 Hikari

SpringBoot 通过 spring-boot-autoconfigure.jar 来自动配置 DataSource。
具体是在 spring.factories 中有一行配置:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

自动加载配置时,就会加载 Hikari 的配置:
HikariDataSource.png

事物连接的关闭/释放: 并不是真正的关闭

事物连接的关闭/释放 并不是真正的关闭,而只是将引用数减 1,当减到 0 的时候,就认为这个连接没有被使用到了。

// org.springframework.jdbc.datasource.ConnectionHolder#released()
/**
 * Releases the current Connection held by this ConnectionHolder.
 * <p>This is necessary for ConnectionHandles that expect "Connection borrowing",
 * where each returned Connection is only temporarily leased and needs to be
 * returned once the data operation is done, to make the Connection available
 * for other operations within the same transaction.
 */
public void released() {
    super.released(); // 不是真正的释放,而只是将引用数减 1
    if (!isOpen() && this.currentConnection != null) {
        if (this.connectionHandle != null) {
            this.connectionHandle.releaseConnection(this.currentConnection);
        }
        this.currentConnection = null;
    }
}

小结

spring-tx 获取连接最终会委托给 DataSourceUtils#doGetConnection() 来获取。
而 DataSourceUtils 在获取连接时,使用的 DataSource 是 spring 管理的一个 bean。
在 SpringBoot 中,默认使用的是 HikariDataSource。具体是在 DataSourceAutoConfiguration 中进行配置的。

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

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

相关文章

2月,还是不要跳槽

新年已经过去&#xff0c;马上就到金三银四跳槽季了&#xff0c;一些不满现状&#xff0c;被外界的“高薪”“好福利”吸引的人&#xff0c;一般就在这时候毅然决然地跳槽了。 在此展示一套学习笔记 / 面试手册&#xff0c;年后跳槽的朋友可以好好刷一刷&#xff0c;还是挺有必…

十四、vue3项目如何使用three.js

近期在开发过程中&#xff0c;因为项目已经接近尾声&#xff0c;就需要对项目中的数据进行整合&#xff0c;而数据看板不失为一个比较直观的展现形式。在数据看板中3D的展现形式是比较流行的展现形式&#xff0c;那么如何在项目引入一个大的场景&#xff0c;并且能够和后台发生…

【NGINX入门指北】Nginx Web 架构实验

Nginx Web 架构实验 文章目录Nginx Web 架构实验一、动态网站结构二、LNMP 动态网站环境部署三、fastcgi & php-fpm&#xff1a;四、php-fpm初始化配置五、Nginx Location、六、Nginx Rewrite七、CA&HTTPS八、Nginx 的平滑升级一、动态网站结构 资源 资源文件识别——…

数据结构---时间复杂度

专栏&#xff1a;数据结构 个人主页&#xff1a;HaiFan. 专栏简介&#xff1a;开学数据结构&#xff0c;接下来会慢慢坑新数据结构的内容&#xff01;&#xff01;&#xff01;&#xff01; 时间复杂度前言1.算法效率1.1如何衡量一个算法的好坏1.2算法的复杂度2.时间复杂度2.1大…

Leetcode力扣秋招刷题路-0073

从0开始的秋招刷题路&#xff0c;记录下所刷每道题的题解&#xff0c;帮助自己回顾总结 73. 矩阵置零 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;mat…

Seata1.5.2安装配置(nacos)+部署

一、seata服务端下载&#xff0c;下载方式介绍两种入口&#xff0c;如下&#xff1a; 1. seata官网 (http://seata.io/zh-cn/blog/download.html) 下载中心 找到对应版本&#xff0c;下载 binary 即可。 下载包名为&#xff1a;seata-server-1.5.2.zip 2. github上下载 Rel…

HIVE 基础(一)

目录 启动hive 方式一 方式二 修改hdfs上给定文件执行的读写权限 创建数据库 查看数据库 查看数据库详细信息 查看当前数据库 创建表 查看建表语句 查看表信息 删除表 添加数据 查看表数据 删除数据库 强制删除数据库 启动hive 方式一 [roothadoop1 ~]# hive 方…

遥感数字图像处理

遥感数字图像处理 来源&#xff1a;慕课北京师范大学朱文泉老师的课程 遥感应用&#xff1a;遥感制图、信息提取 短期内了解知识结构–>有选择的剖析经典算法原理–>系统化知识结构、并尝试实践应用 跳出算法&#xff08;尤其是数学公式&#xff09; 关注原理及解决问…

PowerShell中的对象是神马?

在PowerShell中,无处不在体现出一个概念,这个概念是什么呢?就是对象,对象是面向对象的语言中非常重要的概念,PowerShell的底层是.net,也是面向对象的语言,因此它也继承了面向对象的语言的语法特性。但是很多人在使用PowerShell 语言的时候会觉得有些疑惑,到底什么是Pow…

PCB学习笔记——使用嘉立创在线绘制原理图与PCB

嘉立创软件地址&#xff1a;https://lceda.cn/ 新建工程-新建原理图&#xff0c;在元件库中可以搜索元器件&#xff0c;可以直接放置在原理图上。 原理图绘制完成后&#xff0c;保存文件&#xff0c;设计-原理图转PCB&#xff0c;可以直接生成对应的PCB&#xff0c;设置边框&…

2023美赛 MCM C题 预测结果

背景Wordle是《纽约时报》 目前每天提供的一个流行的谜题。玩家试图通过六次或更少的时间猜 测一个五个字母的单词来解决谜题&#xff0c;每次猜测都会得到反馈。对于这个版本&#xff0c;每个猜测都必 须是一个真实的英语单词。不被比赛认定为文字的猜测是不允许的。Wordle越来…

数影周报:据传国内45亿条快递数据泄露,聆心智能完成Pre-A轮融资

本周看点&#xff1a;据传国内45亿条快递数据泄露&#xff1b;消息称微软解雇150 名云服务销售&#xff1b;消息称TikTok计划在欧洲再开两个数据中心&#xff1b;衣服长时间放购物车被淘宝客服嘲讽&#xff1b;聆心智能完成Pre-A轮融资......数据安全那些事据传国内45亿条快递数…

Centos7 调整磁盘空间

1. 查看磁盘空间占用情况&#xff1a; df -h 可以看到 /home 有很多剩余空间,占了绝大部分&#xff0c; 而我又很少把文件放在home下。 2. 备份 /home 下的内容&#xff1a; cp -r /home/ /homebak/ 3. 关闭home进程&#xff1a; fuser -m -v -i -k /home 报错: -bash: fuser…

C语言编程里的原码, 反码, 补码 你搞懂了吗?

一、机器数和真值 在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念. 1、机器数 一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的&#xff0c;在计算机用一个数的最高位存放符号, 正数为0, 负数为1. 比如&#xff0c;十进制中的数 3 &…

人脸检测的5种方式

文章内容&#xff1a; 1&#xff09;人脸检测的5种方法 1. Haar cascade opencv 2. HOG Dlib 3. CNN Dlib 4. SSD 5. MTCNN 一。人脸检测的5种方法实现 1. Haar cascade opencv Haar是专门用来检测边缘特征的。基本流程如下&#xff1a; 第1步&#xff0c;读取图片 img …

学生党必备的 Keychron 无线机械键盘

学生党必备的 Keychron 无线机械键盘 由于专业需要&#xff0c;之间的键盘使用起来不太舒服&#xff0c;于是准备重新买一个适合工作学习的键盘&#xff0c;于是通过朋友介绍了解到了keychron k3pro,当时也看到网上一些资料说道这款键盘比较到位&#xff0c;今天就来带大家了解…

面试题整理01-集合详解

文章目录前言一、集合的整体结构单列集合接口&#xff1a;双列集合接口&#xff1a;二、单列集合详解1.List接口1.1 ArrayList集合特点&#xff1a;扩容&#xff1a;添加元素遍历1.2 LinkedList集合特点&#xff1a;添加元素&#xff1a;2.Set接口2.1 HashSet集合特点&#xff…

企业维基都说好,今天我们来看看 wiki 软件的缺点有哪些?

企业维基企业wiki和内部知识库可能看起来是一回事——但它们实际上是非常不同的软件类型。也许您可能不知道你在寻找的是知识基础软件&#xff0c;还是wiki软件。 无论哪种方式&#xff0c;缺乏知识都是生产力的巨大瓶颈。事实上&#xff0c;未能分享知识是财富500强企业每年亏…

大话模式学习笔记(简单工厂模式、策略模式、单一职责)

最近在看《大话设计模式》&#xff0c;做一点总结总结吧。 之前也进行学习过设计模式&#xff0c;但是都是讲该设计模式是什么&#xff0c;包含哪些元素&#xff0c;再配合一点简单的demo&#xff0c;理解很不深刻。最近又重新学一下。 简单工厂模式 在这本书中由案例写一个…

【C++】AVL树和红黑树(插入和测试详解)

文章目录1、AVL树1.1 AVL树的插入1.2 总结与测试AVL树2、红黑树2.1 红黑树的插入2.2 红黑树的测试了解AVL树是为了了解红黑树&#xff0c;了解红黑树是为了更好的理解set和map。 1、AVL树 AVL树是在二叉搜索树的基础上进行了严格的平衡&#xff0c;能做到平衡的关键是通过平衡…