数据库连接超时需区分连接建立超时与连接池获取超时:前者因网络或db宕机导致,应快速失败告警;后者因连接耗尽,需检查池配置与泄漏。hikaricp关键参数包括connection-timeout(取连接等待)、max-lifetime(连接最大存活)、idle-timeout(空闲保留时间)。代码中应按sqltransient/nontransientconnectionexception分类捕获处理,配合wait_timeout校准、资源显式关闭、监控与慢查排查。

数据库连接超时不是代码写错,而是资源获取失败的典型场景,核心在于区分“连不上”和“拿不到连接”,并针对性配置与捕获。
明确超时类型:是建立连接超时,还是从连接池取连接超时?
这两类超时触发机制和异常不同,处理方式也不同:
-
连接建立超时:应用尝试和数据库服务器握手失败,比如网络不通、DB服务宕机。常见异常是
java.sql.SQLNonTransientConnectionException或带 “Connection refused” 的SQLException。此时重试意义不大,应快速失败并告警。 -
连接池获取超时:Hikari 等连接池里没有空闲连接可用,且已到最大等待时间。典型异常是
java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after XXXms。这往往说明连接被占满或泄漏,需优先排查池配置和连接使用逻辑。
用 HikariCP 配置关键超时参数
Spring Boot 项目中,在 application.properties 或 application.yml 中设置以下三项最常用:
-
spring.datasource.hikari.connection-timeout=30000(默认30秒):从连接池获取连接的最大等待时间。超时抛SQLTransientConnectionException。 -
spring.datasource.hikari.max-lifetime=1800000(默认30分钟):连接最大存活时间,避免被数据库主动断开后还留在池中失效。 -
spring.datasource.hikari.idle-timeout=600000(默认10分钟):空闲连接在池中保留的最长时间,配合minimum-idle控制保活连接数。
建议初值:connection-timeout 设为 10–15 秒;max-lifetime 比数据库 wait_timeout 小 2–3 分钟(如 MySQL 默认 8 小时,则设为 28000000ms)。
在代码中捕获并区分处理异常
不要只用 catch (SQLException e) 一锅端,应按异常语义分类响应:
- 捕获
SQLTransientConnectionException:属于可恢复瞬态错误,适合加简单重试(如最多 2 次),但需加退避(如首次等 100ms,第二次等 300ms)。 - 捕获
SQLNonTransientConnectionException或含 “Access denied”、“Unknown database” 的 SQLException:不可恢复,应记录错误详情并通知运维,不重试。 - 捕获
SQLTimeoutException(查询执行超时):和连接超时无关,属于 SQL 执行层问题,应优化 SQL 或调大setQueryTimeout(),而非调整连接池。
示例片段:
try {jdbcTemplate.queryForObject("SELECT 1", Integer.class);
} catch (SQLTransientConnectionException e) {
log.warn("获取连接超时,准备重试...", e);
// 触发重试逻辑
} catch (SQLNonTransientConnectionException e) {
log.error("数据库连接不可恢复,请检查DB状态", e);
// 发送告警、熔断等
}
必须做的配套检查
光调参数不治本,以下四点漏掉任一都可能让超时反复发生:
- 确认数据库
wait_timeout和max_connections设置合理(如 MySQL 中show variables like 'wait_timeout';); - 检查代码中所有
Connection、Statement、ResultSet是否在try-with-resources或finally中显式关闭; - 用 Hikari 的监控指标(如
HikariPool-1.pool.ActiveConnections)观察连接使用峰值,验证maximum-pool-size是否足够; - 排查是否有长事务、未索引慢查或锁表操作,导致连接被长期占用无法释放。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











