必须显式调用setFastConnectionFailoverEnabled(true),否则UCP无法响应RAC节点宕机;该方法须在PoolDataSource初始化后、首次获取连接前执行,不能依赖JDBC URL或connectionProperties中的fanEnabled配置。

必须显式启用 FastConnectionFailoverEnabled 才能响应 RAC 节点宕机
UCP 不会从 JDBC URL 或连接属性里自动识别 oracle.jdbc.fanEnabled=true,哪怕服务端 FAN 已开、ONS 连通性验证通过(onsctl ping -h rac1-vip -p 6200 成功),池也不会清理坏连接。常见错误现象是节点宕机后应用仍持续向已下线实例发请求,报 ORA-03113 或 IO Error: Connection reset,重试间隔长达 20–30 秒。
正确做法是在 PoolDataSource 初始化后立即调用:
pool.setFastConnectionFailoverEnabled(true);
这个调用不能省,也不能放在配置文件或连接属性里“间接生效”。若用 Spring Boot,需在 @PostConstruct 或 InitializingBean.afterPropertiesSet() 中执行;若手动 new PoolDataSource,则紧跟在 setConnectionFactoryClassName 和 setInitialPoolSize 之后。
tnsnames.ora 和 JDBC URL 必须禁用 TNS 层重试逻辑
FAILOVER=ON、LOAD_BALANCE=ON、完整的 FAILOVER_MODE 块与 UCP 的 FCF 互斥。两者共存会导致路由混乱:FCF 主动清理连接,TNS 层却还在地址列表里轮询重连,结果连接卡死在已下线节点上不动。
tnsnames.ora 中只保留最简结构:
(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=myrac-scan)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=my_service)))
JDBC URL 必须用 SCAN 地址或 tnsnames 别名,禁用 Easy Connect 格式(如 jdbc:oracle:thin:@//rac1-vip:1521/my_service)。否则 UCP 无法绑定 FAN 事件监听器。
连接亲和性必须靠 connectionLabel 实现,不是靠 URL 或池参数
Oracle UCP 的连接亲和性(Connection Affinity)本质是“把带相同标签的请求尽量复用同一物理连接”,用于保持会话级状态(如临时表、包变量)。它不等于负载均衡,也不等同于绑定某个 RAC 实例。
以下操作完全无效:
setConnectionPoolName("affinity_pool")- 在 JDBC URL 加
?connectTimeout=30 - 设置
minPoolSize或maxPoolSize来“固定”连接数
真正生效的方式是:每次调用 getConnection() 时传入 java.util.Properties,其中包含键值对:
props.setProperty("connectionLabel", "user_id=12345;session_type=report");
UCP 会按 label 哈希匹配空闲连接;label 不同则新建连接。注意 label 值不宜过长或含敏感信息,且要避免高频变更导致连接无法复用。
Spring Boot 集成必须排除 HikariCP 并手动声明 PoolDataSource Bean
Spring Boot 默认装配 HikariDataSource,与 UCP 共存会引发事务绑定错乱、健康检查失效、双池并行初始化等问题——这不是配置问题,是架构冲突。
必须做三件事:
- 在
@SpringBootApplication上加exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class} - 确保
pom.xml中已排除spring-boot-starter-jdbc或spring-boot-starter-data-jpa带来的 HikariCP 传递依赖 - 手动声明
@Bean,且关键参数一个都不能少:setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource")、setInitialPoolSize(5)、setValidateConnectionOnBorrow(false)、setAbandonedConnectionTimeout(300)
漏掉 setInitialPoolSize(5) 会导致首请求同步建连,延迟陡增;用错 connectionFactoryClassName(比如写成 oracle.jdbc.driver.OracleDriver)会直接抛 ClassNotFoundException。
FCF 和连接亲和性都依赖 label 级别的连接生命周期管理,一旦在事务中误用 getPhysicalConnection(),就会绕过 UCP 的所有机制,连接不归还、泄漏、上下文错乱——这种问题在线上很难定位,往往表现为连接数缓慢上涨、活跃连接长期高于预期,且日志里反复出现 UCP 相关警告。


















