Java 11下优化Druid连接Oracle需显式配置三个驱动参数:oracle.jdbc.defaultRowPrefetch=100、oracle.net.CONNECT_TIMEOUT=3000、oracle.jdbc.useFetchSizeWithLongColumn=true;禁用testOnBorrow=true,改用testWhileIdle=true+合理检测间隔;开启PreparedStatement缓存须配对设置poolPreparedStatements=true与maxPoolPreparedStatementPerConnectionSize=50;注意JDBC URL中添加oracle.net.ssl_version=1.2兼容TLS问题。

Java 11 中配置 Druid 连接池优化 Oracle 读写性能,关键不在“换版本”,而在绕开 Oracle JDBC 驱动默认行为与 Druid 参数的隐式冲突——比如 oracle.jdbc.defaultRowPrefetch 未显式设置、testOnBorrow 开启后触发频繁 SELECT 1 FROM DUAL 导致连接争用、以及 poolPreparedStatements 缺失导致硬解析飙升。
Oracle JDBC 驱动必须显式配置的三个参数
Oracle 官方驱动(ojdbc8.jar 或 ojdbc11.jar)在 Java 11 下默认关闭行预取(row prefetch),这会导致单次查询返回大量数据时出现严重网络往返放大。Druid 不会自动帮你设这个,必须手动注入到 connectionProperties:
-
oracle.jdbc.defaultRowPrefetch=100:对大多数 OLTP 查询足够,报表类可调至 500;值过大会吃 JVM 堆内存 -
oracle.net.CONNECT_TIMEOUT=3000:避免 DNS 解析慢拖垮连接获取,尤其在 Kubernetes 内网 DNS 不稳定时 -
oracle.jdbc.useFetchSizeWithLongColumn=true:防止CLOB/BLOB字段读取时触发额外 round-trip
这些要写进 spring.datasource.druid.connection-properties(YAML)或 connectionProperties(properties 文件),不能塞进 JDBC URL,否则 Oracle 驱动不识别。
testOnBorrow=true 在 Oracle 场景下是性能毒药
Oracle 的 SELECT 1 FROM DUAL 虽轻量,但开启 testOnBorrow=true 后,每次取连接都执行一次——高并发下直接变成数据库侧的“无效心跳风暴”。更糟的是,Oracle 默认事务隔离级别为 READ COMMITTED,而 testOnBorrow 会隐式开启一个只读事务再回滚,增加 LGWR 日志压力。
立即学习“Java免费学习笔记(深入)”;
正确做法是关掉它,改用 testWhileIdle=true + 合理的空闲检测间隔:
-
testOnBorrow=false(强制设为 false) testWhileIdle=true-
timeBetweenEvictionRunsMillis=30000(30 秒检查一次空闲连接) -
validationQuery=SELECT 1 FROM DUAL(仅用于空闲检测)
这样既保活,又把检测负载压到后台线程,不干扰业务请求流。
开启 PreparedStatement 缓存必须配对生效
Oracle 对硬解析极其敏感。如果只设 poolPreparedStatements=true 却没设 maxPoolPreparedStatementPerConnectionSize,Druid 默认只缓存 10 个,很快溢出,缓存失效等于没开。
Oracle 场景建议组合配置:
poolPreparedStatements=true-
maxPoolPreparedStatementPerConnectionSize=50(每个物理连接最多缓存 50 个 PS) -
useGlobalDataSourceStat=true(全局统计才能看到 PS 命中率,在监控页看psCacheHitCount/psCacheAccessCount)
上线后务必打开 Druid 监控页(/druid/index.html),点进「SQL」Tab 查看平均解析耗时,若 parseTime > 2ms 且 psCacheHitCount 比例低于 95%,说明 PS 缓存没起效。
Java 11 特定兼容陷阱:JDBC 4.3 与 Oracle 19c+ 的 TLS 握手
Java 11 默认启用 TLSv1.3,而部分 Oracle 19c RAC 集群未完全适配,会导致连接池初始化阶段随机失败,错误形如:java.sql.SQLRecoverableException: IO Error: Connection reset。
临时解法是在 JDBC URL 末尾加参数:
jdbc:oracle:thin:@//host:1521/orcl?oracle.net.ssl_version=1.2
长期方案是升级 Oracle 客户端驱动到 ojdbc11-21.12.0.0 及以上,并确认数据库端已打补丁(Patch 34137968)。别信“加了 -Djdk.tls.client.protocols=TLSv1.2”这种 JVM 全局开关——它会影响整个应用的 HTTPS 调用,得不偿失。



















