查清Oracle端IDLE_TIME是首要步骤,默认10分钟超时会触发ORA-03135;需先用DBA账号查DBA_PROFILES确认,再调整IDLE_TIME并同步配置HikariCP的keepalive-time、minimum-idle、validation-timeout等参数,且修改后须重建连接池生效。

查清Oracle端IDLE_TIME才是第一步
Java应用连Oracle断连,90%不是代码问题,而是Oracle服务端主动踢人。默认IDLE_TIME是10分钟(600秒),超时后Oracle直接关闭socket,后续SQL就会抛ORA-03135: connection lost contact或IO Error: Broken pipe。
别急着改Java配置,先用DBA账号执行:
SELECT resource_name, limit FROM dba_profiles WHERE profile = 'DEFAULT' AND resource_name = 'IDLE_TIME';
如果返回数字(比如30),那就是它——必须改;如果返回UNLIMITED,说明不是这个原因,再查SQLNET.EXPIRE_TIME或防火墙策略。
修改方式有两种:
立即学习“Java免费学习笔记(深入)”;
-
ALTER PROFILE DEFAULT LIMIT IDLE_TIME 60;(单位:分钟) -
ALTER USER app_user PROFILE DEFAULT;(先确保该profile的IDLE_TIME已设为UNLIMITED)
注意:改完不会立即生效,旧连接仍按原值计时,新连接才用新规则。
HikariCP的keepalive-time必须对齐IDLE_TIME
keepalive-time不是心跳频率,而是“空闲连接存活多久后触发一次有效性验证”,只对minimum-idle > 0的连接生效,且仅HikariCP v4.0.3+支持。
关键是对齐Oracle的IDLE_TIME(单位分钟),换算成毫秒后,keepalive-time必须比它小至少2分钟:
- 若Oracle
IDLE_TIME = 30(即1800000ms),则设keepalive-time=1500000(25分钟)较稳妥 -
minimum-idle不能为0,建议设为5,否则没有空闲连接可保活 -
validation-timeout=3000(毫秒),太长会拖慢连接获取
错误做法:keepalive-time设得比IDLE_TIME还大,等于没防;或者用v3.x版本硬配,无效。
connection-test-query已废弃,要用validation-timeout + connection-init-sql
HikariCP 5.0+ 彻底移除了connection-test-query,写了也起不到作用。Oracle场景下正确组合是:
-
connection-init-sql=ALTER SESSION SET CURRENT_SCHEMA = MY_SCHEMA(可选,但能避免每次SQL带schema前缀) -
validation-timeout=3000(必须≤connection-timeout,否则验证失败不触发剔除) -
connection-timeout=30000(获取连接超时,避免卡死)
验证语句本身必须轻量稳定:SELECT 1 FROM DUAL最安全;避免SELECT SYSDATE FROM DUAL(受NLS影响)、SELECT * FROM DUAL WHERE 1=0(返回空集会被判失败)。
驱动和URL写错会导致“假连接”问题
即使所有心跳参数都对,ojdbc版本或URL格式错也会让连接池拿到“假活连接”——isValid()返回true,但一执行SQL就报ORA-03135或Connection reset。
常见坑点:
- Oracle 12c+(尤其19c/21c)必须用
ojdbc8.jar,不能混入ojdbc6传递依赖 - URL必须用service name,不是SID:
jdbc:oracle:thin:@//localhost:1521/ORCLPDB1(注意双斜杠) - 显式设置
driver-class-name=oracle.jdbc.driver.OracleDriver,HikariCP 5+已弃用自动推导
最容易被忽略的是:这些配置改完后,必须重建连接池(重启应用或手动刷新DataSource),旧连接不会自动适配新参数。


















