关于Connection Pool中已有PooledConnection时获取java.sql.Connection的疑问
关于连接池中PooledConnection与Connection句柄的实现机制
先明确几个核心角色的分工:
DataSource:应用层获取连接的统一入口,由连接池厂商实现(比如HikariDataSource、Tomcat JDBC Pool)PooledConnection:连接池对物理数据库连接的包装,持有真正的TCP连接资源- 连接池管理器:隐藏在
DataSource背后的核心逻辑,负责连接的创建、复用、销毁、状态管理
当池中有可用PooledConnection时,如何获取Connection?
当应用调用DataSource.getConnection()且池内有闲置PooledConnection时,流程是这样的:
- 连接池管理器从闲置队列中取出一个
PooledConnection实例 - 该
PooledConnection会生成一个代理版的java.sql.Connection对象返回给应用 - 这个代理对象就是你说的「句柄」,它和底层的
PooledConnection是绑定的
PooledConnection提供Connection的具体方式
PooledConnection本身持有真正的物理数据库连接(比如JDBC驱动原生的Connection实现,对应到数据库的TCP连接)。它提供Connection的核心是动态代理:
- 连接池会通过JDK动态代理或CGLIB生成一个实现
java.sql.Connection接口的代理类 - 这个代理类的所有方法都会被拦截:
- 像
executeQuery()、prepareStatement()这类业务方法,会直接转发给底层的物理连接执行 - 关键的
close()方法会被重写:不会调用物理连接的close()关闭TCP连接,而是通知连接池管理器把当前PooledConnection放回闲置队列,等待下一次复用
- 像
Connection作为PooledConnection句柄的具体机制
这个代理Connection的核心作用是「隔离物理连接和应用层操作」,具体机制:
- 代理对象内部持有对应
PooledConnection的引用,能随时和底层物理连接交互 - 当应用调用
close(),代理会触发PooledConnection的ConnectionEventListener回调(比如connectionClosed()方法),连接池收到通知后将该PooledConnection标记为闲置 - 代理还会做状态校验:如果检测到底层物理连接已经失效(比如数据库重启),会通知连接池销毁这个
PooledConnection,并重新创建新的物理连接返回给应用
你提到的PooledConnection.getConnection()方法,确实是在池内无可用连接时,由连接池管理器调用的——它的作用是创建新的物理连接,并生成对应的代理Connection。而池内有闲置连接时,不需要调用这个方法,直接复用已有的PooledConnection生成新的代理即可。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

