taf在java中依赖连接串、tnsnames.ora和驱动协同生效,缺一不可;failover_mode必须置于connect_data下,jdbc url须引用tnsnames别名并设置tns_admin,ojdbc8+中setfailoverenabled已失效。

TAF 在 Java 中根本不是靠代码配置的,而是靠连接串 + tnsnames.ora + 驱动协同生效;缺一不可,否则即使写了 FAILOVER_MODE 也完全不触发。
tnsnames.ora 中 FAILOVER_MODE 必须嵌套在 CONNECT_DATA 下
很多人把 FAILOVER_MODE 放到 DESCRIPTION 顶层或 ADDRESS_LIST 里,Oracle Net 会静默忽略它——连报错都不会有。
- ✅ 正确位置:
(CONNECT_DATA = (SERVICE_NAME = orcl) (FAILOVER_MODE = (TYPE = SELECT) (METHOD = BASIC) (RETRIES = 3) (DELAY = 5))) - ❌ 错误写法:
(DESCRIPTION = (FAILOVER_MODE = ...) (ADDRESS = ...) (CONNECT_DATA = ...))—— 这个FAILOVER_MODE就是废的 - 漏掉
TYPE或METHOD中任意一个,TAF 就不会启动;TYPE = SESSION和TYPE = SELECT行为差异极大,不能混用
JDBC URL 必须引用 tnsnames 别名,不能用 Easy Connect
jdbc:oracle:thin:@//rac1-vip:1521/orcl 这类格式完全绕过 tnsnames.ora 解析,FAILOVER_MODE 形同虚设。
- ✅ 正确写法:
jdbc:oracle:thin:@RAC(其中RAC是tnsnames.ora里的别名) - 必须提前设置环境变量
TNS_ADMIN指向含tnsnames.ora的目录,比如/etc/oracle/network/admin - Spring Boot 项目中,
spring.datasource.url填@RAC后,还需加spring.datasource.hikari.data-source-properties.oracle.jdbc.fanEnabled=false,否则 FAN 会干扰 TAF
ojdbc8+ 驱动下 setFailoverEnabled(true) 已失效
这个方法在 ojdbc8 及以后版本被标记为 @Deprecated,调用它既不报错也不起效——TAF 是 Oracle Net 层能力,JDBC 驱动只负责透传连接参数。
- ✅ 唯一有效方式:所有 TAF 参数必须出现在连接串里,例如:
(DESCRIPTION=(FAILOVER=true)(ADDRESS_LIST=...)(CONNECT_DATA=(SERVICE_NAME=...)(FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC)(RETRIES=3)(DELAY=5)))) -
FAILOVER=true是开关,不写它,整个FAILOVER_MODE块都会被忽略 -
METHOD=PRECONNECT在 ojdbc8+ 中已废弃,设了也白设;TYPE=SELECT才支持查询续跑,但 DML 仍会报ORA-25402并回滚
TAF 不是无感切换,应用必须捕获并重试异常
故障瞬间一定会抛异常:SQLException 带 SQLState=08006,或具体错误码如 ORA-03113、ORA-03114。这不是配置失败,而是 TAF 正常行为。
- 如果业务逻辑没做异常捕获和重试,线程直接挂掉,TAF 就毫无意义
-
TYPE=SELECT虽能续查,但每个 session 的 PGA 会多预留 2–5 MB,高并发下内存压力陡增 - 普通 OLTP 场景建议用
TYPE=SESSION;只有长时只读查询(如报表导出)才考虑TYPE=SELECT
最容易被忽略的是:VIP 主机名必须能在 Java 进程所在机器上解析,否则连 tnsping RAC 都通不过,更别说 TAF 生效;/etc/hosts 里漏写任一 VIP,就会报 ORA-12545。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











