老王读Spring Transaction-6spring-tx与DataSource连接池整合的原理
Posted 老王学源码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了老王读Spring Transaction-6spring-tx与DataSource连接池整合的原理相关的知识,希望对你有一定的参考价值。
@TOC
前言
javax.sql.DataSource
是 java 提供的一个获取 DB 连接的标准接口。
它的实现类可以通过简单的实现,生成标准的连接对象;也可以使用连接池方式实现,生成的池化的连接对象。
通常在企业级的开发当中,我们都会使用池化的连接对象,比如使用 apache 的 DBCP 连接池、阿里的 druid 连接池、springboot 默认使用的 hikari 连接池等
那么,DataSource 是如何与 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()
来获取。
事物连接: 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 Connection
与 Spring-managed transactional Connections
是有区别的。
通常所说的 JDBC Connection
是普通的 jdbc 连接。而 Spring-managed transactional Connections 是受 Spring 管理的事物连接(通常 @Transactional 标记的事物方法使用的就是 Spring 管理的事物连接)。
可以通过 DataSourceUtils#isConnectionTransactional(Connection con, DataSource dataSource)
方法去判断一个 jdbc 连接是否是一个 Spring 管理的事物连接。
而非事物连接通常也是从 DataSource 中获取的,只是这些非事物连接不是被事物管理器 DataSourceTransactionManager
来管理的。
DataSourceTransactionManager 的类图如下:
spring-tx 与 DataSource 的整合
TransactionManager 自动配置的源码:
可以看到,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 的配置:
事物连接的关闭/释放: 并不是真正的关闭
事物连接的关闭/释放 并不是真正的关闭,而只是将引用数减 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
中进行配置的。
以上是关于老王读Spring Transaction-6spring-tx与DataSource连接池整合的原理的主要内容,如果未能解决你的问题,请参考以下文章
老王读Spring IoC-5Spring IoC 小结——控制反转依赖注入
老王读Spring IoC-2Spring IoC之BeanDefinition扫描注册的原理
老王读Spring Transaction-4Spring事务管理的核心原理——PlatformTransactionManager&TransactionStatus
老王读Spring Transaction从EnableTransactionManagement顺藤摸瓜,研究@Transactional的实现原理
老王读Spring Transaction-6spring-tx与DataSource连接池整合的原理
#yyds干货盘点# 老王读Spring AOP-4Spring AOP 与Spring IoC 结合的过程 && ProxyFactory 解析