连接借还生命周期
This content is not available in your language yet.
HikariCP 的连接生命周期围绕 PoolEntry 展开:物理连接只由池创建和销毁,业务拿到的是带生命周期回调的代理连接。
先给答案:HikariCP 的连接生命周期围绕 PoolEntry 展开:物理连接只由池创建和销毁,业务拿到的是带生…
Section titled “先给答案:HikariCP 的连接生命周期围绕 PoolEntry 展开:物理连接只由池创建和销毁,业务拿到的是带生…”HikariCP 的连接生命周期围绕 PoolEntry 展开:物理连接只由池创建和销毁,业务拿到的是带生命周期回调的代理连接。 正文沿“借出 -> 归还 -> 创建与补充”展开:先确认入口和状态归属,再跟踪控制流或数据流的推进,最后落到对外可观察的结果。
主要失效边界集中在“借出超时、归还失败、minIdle 不足”这些场景。它们破坏的是容量、顺序、并发或生命周期前提;排查时应先确认状态是否仍由正确对象持有,再核对推进条件和清理路径。
HikariPool#getConnection():src/main/java/com/zaxxer/hikari/pool/HikariPool.java:140-142。- 带超时借出:
:152-183。 connectionBag.borrow::160。- 条目失效关闭:
:167。 - 等待指标:
:171。 - 代理创建:
:179。 PoolEntry#createProxyConnection:PoolEntry.java:99-101。
借出时如果拿到已标记驱逐或已死亡的条目,池会关闭它并继续尝试;只有有效条目才包装成代理返回。
HikariPool#recycle:HikariPool.java:434-447。- 指标记录使用时间:
:436。 - 已驱逐条目转关闭:
:438。 - 正常条目回到 bag:
:447。 - 物理关闭:
closeConnection在:457-463。
createPoolEntry:HikariPool.java:485-504。- maxLifetime 定时任务:
:495。 - keepalive 定时任务:
:498-503。 addBagItem::341。- 创建任务提交:
:528-533。 - 新物理连接:
PoolBase.java:360-373。
为什么归还时才重置而不是借出时重置
Section titled “为什么归还时才重置而不是借出时重置”替代方案:每次借出前检查并修复所有 JDBC 状态。
为什么不行:状态污染应在上一个租借结束时收口,借出热路径只需确认条目可用;把重置延迟到 close 还能把异常归因到上一位使用者。
证据:ProxyConnection.java:240-262 关闭时先处理 rollback,再调用 PoolEntry.resetConnectionState,随后由 HikariPool.recycle 重新入 bag。
| 场景 | 现象 | 原因 | 规避 |
|---|---|---|---|
| 借出超时 | SQLTransientConnectionException |
active 达上限且无空闲连接 | 调整池大小或减少持有时间 |
| 归还失败 | 连接被驱逐 | 状态重置或 close statement 出错 | 记录 closureReason 并重建 |
| minIdle 不足 | 高峰期创建延迟 | 后台补充尚未完成 | 结合启动策略和数据库容量配置 |
池化资源必须区分“资源本体”和“租借代理”。代理负责把租借结束转换成统一回收动作,池才有机会在一个位置完成状态清理和故障判断。
面试锚点
- HikariPool 为什么返回代理连接?
- 失效条目在借出过程中如何处理?
recycle和物理close的区别是什么?