HikariCP的leak-detection-threshold未报警,主因是日志级别不足(需设为DEBUG)和阈值设置不合理(Oracle场景建议30000ms);CLOSE_WAIT表明TCP层已断连但连接未归还,属物理层泄露恶化;手动获取Connection后未显式关闭PreparedStatement和ResultSet,或MyBatis ResultHandler未读完就返回,均导致游标泄漏与连接“假释放”。
为什么HikariCP的leak-detection-threshold没报警?
不是配置没生效,而是日志级别和阈值设置共同导致“静默泄露”。hikaricp默认只在warn级别输出泄露警告,但spring boot默认把com.zaxxer.hikari设为info或更低,日志直接被过滤掉。
- 必须在
application.yml里显式提升日志级别:logging.level.com.zaxxer.hikari: DEBUG -
leak-detection-threshold别设0(默认关闭),Oracle场景下建议从30000(30秒)起步;设5000容易因网络抖动误报,设120000会让问题延迟暴露 - 泄露日志里出现
CLOSE_WAIT状态,说明连接已断开但TCP残留——这不是Java层代码问题,而是泄露已进入物理层恶化阶段
JdbcTemplate手动拿Connection后为什么连接不归还?
JdbcTemplate自动管理连接的前提是全程走它的封装方法(如query()、update())。一旦你调用jdbcTemplate.getDataSource().getConnection()拿到原始Connection,后续所有PreparedStatement和ResultSet都必须显式关闭,JdbcTemplate完全不介入。
- 错误写法:
Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement("..."); ps.executeUpdate();→ps和conn都没关 - 正确写法:用
try-with-resources包裹Connection和PreparedStatement,且确保conn.close()被执行(连接池下close()实际是归还) - 更稳妥方案:直接用
JdbcTemplate.batchUpdate(String sql, BatchPreparedStatementSetter setter),它内部复用同一PreparedStatement,避免游标爆炸
MyBatis流式查询ResultHandler没读完就return会怎样?
MyBatis的selectCursor()或fetchSize > 0 + ResultHandler底层仍依赖OracleResultSet。如果handleRow()中途return或抛异常,未消费完的ResultSet会导致游标卡在Oracle会话里——GC不保证及时回收,尤其高并发下。
- 必须确保
ResultHandler.handleRow()完整遍历,或在finally块中显式关闭Cursor(若可访问) - 避免在
handleRow()里做耗时操作或提前退出逻辑;如需中断,应改用分页查询+limit/offset - PL/SQL中返回
REF CURSOR时,务必在存储过程末尾CLOSE该游标,否则Java端即使关闭ResultSet也无效
循环拼接SQL导致ORA-01000游标耗尽的根本原因
ORA-01000本质不是数据库参数不够大,而是应用端持续泄漏游标句柄——哪怕连接已归还池中,游标仍绑定在Oracle会话里不释放。
- 每次调用
conn.prepareStatement("UPDATE t SET v = " + i),Oracle都会解析为新语句、分配新游标;循环500次=500个未关闭游标 - ❌ 禁止在循环内拼接SQL;✅ 改用参数化
"UPDATE t SET v = ?"+BatchPreparedStatementSetter - Druid/Hikari默认开启
cachePrepStmts=true,但“缓存”不等于“复用”:SQL字符串不同,就绝不复用,只缓存解析结果 - 验证是否为缓存引发:JDBC URL加
&cachePrepStmts=false&prepStmtCacheSize=0临时禁用,观察游标增长是否停止
@Select方法没加@Transactional,或SqlSessionTemplate脱离Spring生命周期管理——连接看似close()了,实则没真正归还池。这类问题必须靠DEBUG日志+堆栈捕获才能定位到具体代码行。


















