Oracle JDBC URL 必须使用 service_name(如@//host:1521/ORCLPDB1)而非 SID(如@host:1521:ORCL),否则报 ORA-12505;HikariCP 的 connection-timeout 应 ≥30000ms,validation-timeout ≤ connection-timeout 且建议 5000~10000ms;必须显式设 auto-commit=false 并配合 connection-init-sql;statement-cache-size 和 fetch-size 对性能影响显著。
Oracle JDBC URL 里必须带 service_name 而不是 SID
oracle 12c+ 默认用 service_name,但很多人沿用老习惯写 sid=orcl,结果连得上却报 ora-12505: tns:listener does not currently know of sid given in connect descriptor。hikaricp 不会帮你校验这个,错误直接透传给驱动。
- 正确写法:
jdbc:oracle:thin:@//host:1521/ORCLPDB1(ORCLPDB1是 service_name) - 错误写法:
jdbc:oracle:thin:@host:1521:ORCL(这是 SID 格式,只适用于非容器库或 legacy 配置) - 不确定时,登录数据库查:
SELECT SYS_CONTEXT('USERENV', 'SERVICE_NAME') FROM DUAL;
HikariCP 的 connection-timeout 和 validation-timeout 必须大于 Oracle 网络超时
Oracle JDBC 驱动默认的网络读超时是 0(无限),但实际环境常受防火墙、LB 或中间件限制。如果 HikariCP 的 connection-timeout 设太小(比如 3000),连接还没走到 Oracle 就被池子主动丢弃,日志里只看到 Connection is not available, request timed out after 3000ms,容易误判为数据库负载高。
-
connection-timeout建议 ≥ 30000(30 秒),给底层驱动留出重试和握手时间 -
validation-timeout必须 ≤connection-timeout,且建议设为 5000~10000;Oracle 的SELECT 1 FROM DUAL通常在毫秒级,设太高反而拖慢连接获取 - 别依赖
connection-test-query:Oracle 用isValid()更轻量,HikariCP 5.0+ 默认就走这个,无需额外配
Oracle 需要显式关闭 auto-commit,否则事务行为异常
HikariCP 默认不干预连接的 auto-commit 状态,而 Oracle JDBC 驱动默认是 true。这意味着你手动 conn.commit() 可能没效果,或者 Spring @Transactional 失效——因为连接一从池里拿出来就是已提交状态。
- 必须配置:
connection-init-sql=ALTER SESSION SET CURRENT_SCHEMA=YOUR_SCHEMA+auto-commit=false - 更稳妥的做法是在
connection-init-sql里加:SET AUTOCOMMIT OFF(注意:Oracle 驱动支持该 SQL,但仅限 thin 模式) - Spring Boot 用户注意:
spring.datasource.hikari.auto-commit=false这个配置只影响 HikariCP 初始化时是否调用setAutoCommit(false),它有效,但不如在 init-sql 里双保险
Oracle 的 statement-cache-size 和 fetch-size 对批量查询影响极大
HikariCP 本身不缓存 Statement,但 Oracle 驱动有内部语句缓存。如果没开,每次 PreparedStatement 都触发硬解析,高并发下 CPU 直接飙到 100%;fetch-size 则直接影响分页和大结果集的内存占用。
- 在 JDBC URL 后追加:
?implicitStatementCacheSize=256&oracle.jdbc.fanEnabled=false(禁用 FAN 避免 RAC 环境下的额外心跳) - HikariCP 配置
statement-cache-size=256(注意:这是 HikariCP 5.0+ 才支持的参数,旧版无效) - 代码中显式设 fetch size:
stmt.setFetchSize(1000);Oracle 默认是 10,查 10 万行可能 OOM
auto-commit=false 和 service_name 格式,这两处一错,其他参数再优也白搭。











