数据库连接池实现连接复用的核心思路是“预先创建连接、缓存连接、复用连接”,通过对连接的生命周期进行统一管理,避免频繁创建和关闭连接的性能损耗。具体实现机制如下:
连接池的本质是一个“连接缓存容器”,内部维护着一批处于“空闲状态”的数据库连接(Connection)。当客户端需要访问数据库时,从池中获取空闲连接;使用完毕后,不直接关闭连接,而是将其“归还”到池中供下次复用。这个循环过程避免了连接的重复创建和销毁,实现复用。
连接池启动时,会根据配置的“初始连接数”(如 initialSize),批量创建数据库连接(通过 JDBC 的 DriverManager.getConnection()),并将这些连接标记为“空闲状态”,存入内部的连接缓存容器(通常是线程安全的队列或集合,如 ConcurrentLinkedQueue)。
示例配置(以 Druid 为例):
# 初始连接数:启动时创建5个连接
spring.datasource.druid.initial-size=5当客户端(如 MyBatis、JDBC 代码)请求连接时,连接池执行以下操作:
maxActive),则创建新连接并返回。 示例配置:
# 最大连接数:最多创建20个连接
spring.datasource.druid.max-active=20
# 等待连接超时时间:5秒未获取到连接则报错
spring.datasource.druid.max-wait=5000客户端使用连接完成数据库操作后,不会调用 Connection.close() 关闭连接(原生 JDBC 会关闭),而是通过连接池提供的“代理连接”将其归还给池:
Connection 进行“代理”(如使用动态代理模式),重写 close() 方法: close() 时,代理逻辑不会真正关闭连接,而是将连接标记为“空闲状态”,重新存入缓存容器。 SELECT 1 验证连接是否有效),若无效则销毁并创建新连接补充。 为保证资源高效利用,连接池会通过后台线程动态调节连接数量:
minIdle):若空闲连接数低于此值,自动创建新连接补充。 minEvictableIdleTimeMillis):若连接长时间(如 30 分钟)未被使用,自动销毁以释放资源。 示例配置:
# 最小空闲连接数:保证至少3个空闲连接
spring.datasource.druid.min-idle=3
# 空闲连接超时时间:30分钟未使用则销毁
spring.datasource.druid.min-evictable-idle-time-millis=1800000连接复用的核心技术是“连接代理”,它解决了“客户端调用 close() 却不真正关闭连接”的问题:
Connection 接口),代理类持有原生连接的引用。 close() 方法:不执行 socket.close() 等真正关闭连接的操作,而是将连接状态重置(如清除事务残留信息),并归还给连接池的缓存容器。 prepareStatement()、commit())则直接调用原生连接的对应方法,保证正常功能。 伪代码示意:
// 代理连接类
class ProxyConnection implements Connection {
private Connection realConnection; // 原生连接
private ConnectionPool pool; // 连接池引用
@Override
public void close() {
// 不关闭真实连接,而是归还到池
pool.returnConnection(this);
}
// 其他方法(如prepareStatement)直接调用真实连接
@Override
public PreparedStatement prepareStatement(String sql) {
return realConnection.prepareStatement(sql);
}
}通过“预先创建、缓存管理、代理回收、动态调节”四个环节,连接池实现了连接的高效复用,主要带来两大收益:
这也是为什么生产环境中必须使用连接池(如 HikariCP、Druid),而非直接使用原生 JDBC 连接的原因。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。