• 深挖 Spring Boot:8 种数据库连接控制机制,哪个才是你的最优解?

深挖 Spring Boot:8 种数据库连接控制机制,哪个才是你的最优解?

2025-06-06 10:00:09 栏目:宝塔面板 89 阅读

在企业级开发中,数据库连接是系统资源中最昂贵、最敏感的组件之一。Spring Boot 借助其灵活而强大的数据库访问基础设施,为连接的获取、绑定、释放与事务整合提供了完备方案。本文将以深入浅出的方式,解构 Spring 提供的 8 种数据库连接控制手段,帮助你全面理解连接背后的运作机制与使用场景。

1、基于 DataSource 的连接机制

核心思想:

Spring 推荐使用 javax.sql.DataSource 作为统一的连接工厂接口,它屏蔽了底层连接池实现的细节,使得我们能更专注于业务代码开发。

实现逻辑详解:

Spring Boot 自动配置会读取 application.yml 中的相关属性并创建数据源实例。通常采用连接池技术(如 HikariCP),通过 DataSourceBuilder 构建连接池对象。例如:

@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public DataSource dataSource(DataSourceProperties properties) {
    return DataSourceBuilder.create()
        .type(HikariDataSource.class)
        .driverClassName(properties.getDriverClassName())
        .url(properties.getUrl())
        .username(properties.getUsername())
        .password(properties.getPassword())
        .build();
}

此方式重点在于配置灵活性强,并结合连接池实现了线程复用、连接限流等能力,是企业级开发的首选方式。

2、使用 DataSourceUtils 简化连接释放流程

核心思想:

org.springframework.jdbc.datasource.DataSourceUtils 提供了对数据库连接的透明管理,主要解决的问题是:在事务上下文中确保使用的是 Spring 管理的连接。

实现逻辑详解:

  • 在执行数据库操作时,通过 DataSourceUtils.getConnection() 自动检查当前线程是否已绑定连接。
  • 若绑定,则复用当前连接;否则新建并绑定;
  • 释放连接时,releaseConnection() 会判断事务状态,在事务尚未提交或回滚前不会关闭连接。
Connection conn = DataSourceUtils.getConnection(dataSource);
// 这里获取的 Connection 是事务感知的
DataSourceUtils.releaseConnection(conn, dataSource);

该机制保障了同一事务上下文中的所有 JDBC 操作使用的是同一个物理连接,保障了原子性。

3、实现 SmartDataSource:决定是否关闭连接

核心思想:

SmartDataSource 是 Spring 扩展的接口,旨在控制连接的释放行为。相比标准 DataSource接口,它多了一个 shouldClose() 方法,用来告知容器连接是否应该被物理关闭。

实现逻辑详解:

使用 DataSourceUtils.releaseConnection() 释放连接时,内部会判断数据源是否为 SmartDataSource,如果返回 false,则连接不会关闭,而是保留用于后续复用。

public interface SmartDataSource extends DataSource {
    boolean shouldClose(Connection con);
}

适合那些需保持长连接但又不希望频繁开关连接的场景(如:批处理、连接代理等)。

4、自定义数据源?继承 AbstractDataSource 即可

核心思想:

Spring 的 AbstractDataSource 是一个辅助开发的抽象基类,帮助你快速实现自定义 DataSource。它已实现了接口的基础逻辑,开发者只需聚焦于 getConnection() 方法即可。

实现逻辑详解:

public class CustomDataSource extends AbstractDataSource {
    @Override
    public Connection getConnection() throws SQLException {
        return actualDataSource.getConnection();
    }


    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return actualDataSource.getConnection(username, password);
    }
}

适用于你需要对连接获取过程进行代理、增强(如加密解密、限流、审计)等操作的场景。

5、SingleConnectionDataSource:重用单个连接

核心思想:

该类实现 SmartDataSource,只维护单一物理连接,每次调用 getConnection() 实际返回的是该连接的代理对象。这种方式主要用于测试或简化环境中的连接重用。

实现逻辑详解:

  • 每次调用返回的 Connection 是代理对象;
  • 如果设置了 suppressClose=true,即使执行 close() 也不会关闭连接;
  • 不支持并发访问,因此不可用于生产环境。

适合那些对连接一致性要求较高、频繁测试同一连接上下文行为的场合,如报表、数据库回归测试等。

6、DriverManagerDataSource:非连接池的 DataSource

核心思想:

该类是直接基于 DriverManager 实现的连接工厂。每次调用 getConnection() 都会返回一个全新的连接,无连接池,适合快速测试或临时脚本用途。

实现逻辑详解:

@Bean
public DriverManagerDataSource dataSource() {
    DriverManagerDataSource ds = new DriverManagerDataSource();
    ds.setDriverClassName("org.hsqldb.jdbcDriver");
    ds.setUrl("jdbc:hsqldb:hsql://localhost/");
    ds.setUsername("sa");
    ds.setPassword("");
    return ds;
}

因频繁创建物理连接导致资源开销大,不推荐在高并发或生产环境中使用。

7、TransactionAwareDataSourceProxy:让遗留代码支持事务

核心思想:

该代理类包装一个常规 DataSource 实例,为其添加 Spring 事务感知能力,使得即使是非 Spring 管理的 DAO 代码也能“被动”参与到事务控制中。

实现逻辑详解:

  • 获取连接时判断当前线程是否存在事务;
  • 如果有,则复用事务绑定连接;
  • 如果没有,则正常获取新连接;

常用于整合遗留系统或第三方库代码的场景。它是非侵入式的事务集成方式。

@Bean
public DataSource transactionAwareDataSource() {
    return new TransactionAwareDataSourceProxy(realDataSource());
}

8、DataSourceTransactionManager:显式管理事务

核心思想:

DataSourceTransactionManager 是 Spring 原生的事务管理器,用于管理基于 JDBC 的事务。它绑定数据库连接到当前线程,控制事务的开始、提交与回滚。

实现逻辑详解:

  • 事务开启时,通过 DataSourceUtils 获取连接并与线程绑定;
  • 调用 commit() 或 rollback() 控制物理连接行为;
  • 最终通过 releaseConnection() 释放连接。
@Bean
public PlatformTransactionManager txManager(DataSource dataSource) {
    DataSourceTransactionManager tx = new DataSourceTransactionManager();
    tx.setDataSource(dataSource);
    tx.setDefaultTimeout(10); // 设置默认事务超时时间
    return tx;
}

这是 Spring 框架 JDBC 模块的事务控制核心,适用于所有单库 JDBC 场景,是声明式事务 @Transactional 背后的底层支持。

总结

控制方式

是否支持事务绑定

是否连接池

是否线程安全

用途

DataSource

✅(需结合工具类)

✅(取决于实现)

主流配置入口

DataSourceUtils

内部连接协调

SmartDataSource

❌/✅

灵活释放控制

AbstractDataSource

依赖实现

自定义扩展

SingleConnectionDataSource

测试环境专用

DriverManagerDataSource

快速演示、测试

TransactionAwareDataSourceProxy

适配第三方遗留代码

DataSourceTransactionManager

事务控制主力

本文地址:https://www.yitenyun.com/271.html

搜索文章

Tags

数据库 API FastAPI Calcite 电商系统 MySQL Web 应用 异步数据库 数据同步 ACK 双主架构 循环复制 Deepseek 宝塔面板 Linux宝塔 Docker 生命周期 JumpServer JumpServer安装 堡垒机安装 Linux安装JumpServer esxi esxi6 root密码不对 无法登录 web无法登录 序列 核心机制 Windows Windows server net3.5 .NET 安装出错 宝塔面板打不开 宝塔面板无法访问 SSL 堡垒机 跳板机 HTTPS 查看硬件 Linux查看硬件 Linux查看CPU Linux查看内存 无法访问宝塔面板 Windows宝塔 Mysql重置密码 HTTPS加密 连接控制 机制 ES 协同 Oracle 处理机制 Serverless 无服务器 语言 OB 单机版 scp Linux的scp怎么用 scp上传 scp下载 scp命令 Spring SQL 动态查询 技术 存储 缓存方案 缓存架构 缓存穿透 日志文件 MIXED 3 分页查询 索引 运维 架构 InnoDB Rsync 响应模型 修改DNS Centos7如何修改DNS RocketMQ 长轮询 配置 监控 HexHub Linux 安全 服务器 MySQL 9.3 Redis 电商 系统 异步化 防火墙 黑客 聚簇 非聚簇 查询 sftp 服务器 参数 数据 主库 group by SQLark PostgreSQL 自定义序列化 管理口 业务 数据库锁 SQLite-Web SQLite 数据库管理工具 线上 库存 预扣 Doris SeaTunnel MVCC 人工智能 向量数据库 推荐系统 R edis 线程 开源 存储引擎 共享锁 PG DBA 网络架构 工具 网络配置 加密 场景 AI 助手 Ftp ​Redis 机器学习 推荐模型 流量 数据备份 • 索引 • 数据库 RDB AOF 缓存 redo log 重做日志 高可用 Python B+Tree ID 字段 优化 万能公式 Redis 8.0 核心架构 订阅机制 Canal 信息化 智能运维 网络故障 INSERT COMPACT GreatSQL 连接数 同城 双活 云原生 微软 SQL Server AI功能 Hash 字段 不宕机 Web Postgres OTel Iceberg IT运维 prometheus Alert 自动重启 Netstat Linux 服务器 端口 引擎 性能 大模型 SVM Embedding 向量库 Milvus Entity 开发 分库 分表 高效统计 今天这篇文章就跟大家 虚拟服务器 虚拟机 内存 崖山 新版本 OAuth2 Token ZODB 单点故障 DBMS 管理系统 MongoDB 容器 sqlmock mini-redis INCR指令 JOIN Undo Log 容器化 LRU 悲观锁 乐观锁 数据集成工具 分布式 集中式 SpringAI openHalo 磁盘架构 窗口 函数 排行榜 排序 数据脱敏 加密算法 Redisson 锁芯 QPS 高并发 Testcloud 云端自动化 Redka PostGIS 启动故障 大表 业务场景 分页 数据结构 EasyExcel MySQL8 意向锁 记录锁 聚簇索引 非聚簇索引 数据类型 模型 原子性 StarRocks 数据仓库 Recursive 分布式架构 分布式锁​ Pottery AIOPS R2DBC 1 事务 Java IT Caffeine CP InfluxDB RAG HelixDB 工具链 发件箱模式 SSH MCP 开放协议 网络 Web 接口 dbt 数据转换工具 filelock 池化技术 连接池 数据分类 部署 对象 字典 传统数据库 向量化 读写 速度 服务器中毒 Go 数据库迁移 事务隔离 分页方案 排版 数据页 优化器 单线程 仪表盘 双引擎 Order 频繁 Codis 线程安全 LLM Crash 代码 List 类型 订单 Pump 事务同步 UUIDv7 主键 日志 Ansible