必须显式调用setFastConnectionFailoverEnabled(true),否则RAC节点宕机后连接池无感知,持续报ORA-03113或IO Error;该方法须在PoolDataSource初始化后、首次获取连接前执行,不能依赖JDBC URL或connectionProperties中的fanEnabled配置。

必须显式调用 setFastConnectionFailoverEnabled(true),否则 RAC 节点宕机后连接池完全无感知,首请求卡顿、ORA-03113、IO Error 会持续出现。
FCF 不是靠 JDBC URL 开关自动生效的
很多人以为在 JDBC URL 里加 oracle.jdbc.fanEnabled=true 就够了,实际完全无效。UCP 的快速连接故障转移(FCF)是独立控制的运行时行为,必须在 PoolDataSource 实例初始化后手动开启:
-
pool.setFastConnectionFailoverEnabled(true)是唯一有效入口,漏掉这行等于没配 FCF - 仅设连接属性(
setConnectionProperties)或 URL 参数,UCP 根本不读取该开关 - Spring Boot 场景下需在
@PostConstruct或InitializingBean.afterPropertiesSet()中执行,不能写在构造函数里 - 验证是否生效:启动后查日志是否有
FCF enabled for service;或故意 kill 一个 RAC 实例,观察应用是否在 2–5 秒内自动切到健康节点(而非等超时重试)
tnsnames.ora 和 JDBC URL 必须严格匹配 FCF 要求
FCF 依赖服务端 FAN 事件推送,而事件路由靠 service name + ONS 通路 + SCAN 地址三者对齐。任何一环错位都会让 FCF 失效:
- JDBC URL 必须使用 SCAN 地址或
tnsnames.ora别名,禁用 Easy Connect 格式(如jdbc:oracle:thin:@//rac1-vip:1521/my_service) -
tnsnames.ora中只保留最简结构:(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=myrac-scan)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=my_service))) - 必须彻底删除
FAILOVER=ON、LOAD_BALANCE=ON、FAILOVER_MODE块——它们和 FCF 互斥,共存会导致连接卡死在已下线节点 - 确认 service 已启用 FAN:
srvctl config service -db <db_name> -service <service_name>输出中含FAILOVER_TYPE=SELECT或SESSION
连接亲和性要用 connectionLabel,不是靠池配置或 URL
Oracle UCP 的连接亲和性(Connection Affinity)本质是“标签路由”,不是实例绑定。它只在你主动传入 label 时才起作用,且必须配合业务逻辑设计:
立即学习“Java免费学习笔记(深入)”;
- 获取连接时必须传
java.util.Properties,其中含connectionLabel键值对,例如:props.put("connectionLabel", "tenant_id=123") -
pool.getConnection(props)才会触发亲和逻辑;只调getConnection()默认无标签,不参与路由 - 不要误用
setConnectionPoolName()或 URL 参数(如?connectTimeout=30),这些对亲和性完全无效 - 典型场景:多租户系统中,同一租户的请求尽量复用同一条物理连接,以保持临时表、包变量等会话状态
Java 11 下容易忽略的兼容性细节
UCP 在 Java 11 上运行没问题,但几个底层依赖项若版本不匹配,会导致类加载失败或功能降级:
- 必须用
ojdbc8.jar(支持 Java 8–17),ojdbc10.jar或ojdbc11.jar在 Java 11 下反而可能因模块化限制报NoClassDefFoundError -
setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource")是唯一安全写法;填oracle.jdbc.driver.OracleDriver会抛IllegalStateException或ClassNotFoundException - 若项目启用了 Java 模块系统(
module-info.java),需显式requires oracle.ucp;和requires oracle.jdbc;,否则PoolDataSourceFactory可能无法反射加载 - 避免混用 Spring Boot 自动配置:必须排除
DataSourceAutoConfiguration,否则 HikariCP 和 UCP 双池并行,事务上下文错乱
真正难的不是写那几行代码,而是把 FCF 的三个前提(FAN service、ONS 连通、URL/tnsnames 精确匹配)全部验证到位——少一个,就等于没配。


















