failover_mode必须作为connect_data的直接子项,且jdbc需通过tnsnames别名连接并正确设置tns_admin环境变量,否则taf不生效。

tnsnames.ora里FAILOVER_MODE位置写错
Oracle Net 只认一种结构:FAILOVER_MODE 必须作为 CONNECT_DATA 的直接子项,放错就等于没写。驱动静默忽略,不报错、不打日志,但 TAF 从不生效。
- ✅ 正确写法:
(CONNECT_DATA = (SERVICE_NAME = mypdb) (FAILOVER_MODE = (TYPE = SESSION) (METHOD = BASIC))) - ❌ 错误写法:
(DESCRIPTION = (FAILOVER_MODE = ...))—— 参数被完全跳过 - ❌ 错误写法:
(ADDRESS_LIST = (FAILOVER_MODE = ...) (ADDRESS = ...))—— 同样无效
JDBC 连接没走 tnsnames 别名
ojdbc8/jdbc11 驱动只在解析 tnsnames.ora 时读取 FAILOVER_MODE。用 Easy Connect 格式(如 jdbc:oracle:thin:@//rac1-vip:1521/orcl)直连,TAF 彻底不启动,故障时必抛 ORA-03113 或连接重置。
- 必须用 tnsnames 别名:JDBC URL 写成
jdbc:oracle:thin:@RACDB,不能是 IP/SCAN/VIP 直连 - 启动 Java 进程前,必须设置
TNS_ADMIN环境变量,指向含tnsnames.ora的目录 - Spring Boot 中
spring.datasource.url传别名后,仍需确保TNS_ADMIN生效,否则别名解析失败
TYPE 和 METHOD 配对错误导致行为异常
TYPE 决定“故障后做什么”,METHOD 决定“什么时候做”。配错不是失效,而是产生不可控副作用。
-
TYPE = SELECT+METHOD = BASIC:只对已打开游标有效,且要求 JDBC 显式设ResultSet.HOLD_CURSORS_OVER_COMMIT,普通应用不配就仍断 -
TYPE = SESSION+METHOD = BASIC:最稳组合。实例宕机后重建会话,事务重发,SELECT 自动重执行 -
METHOD = PRECONNECT:ojdbc8+ 已废弃,设了也不生效;若旧驱动误用,可能触发ORA-12519(连接数超限)
RETRIES × DELAY 超出业务容忍窗口
TAF 故障转移耗时 ≈ RETRIES × DELAY 秒。这个值不是越大越好,而是要和应用层超时对齐。
- 设
RETRIES=180、DELAY=5→ 最长等 15 分钟才放弃,但 HTTP 接口通常 30 秒就返回504 Gateway Timeout - 设
DELAY=1且RETRIES过大 → 连续快速重试可能被监听器限流或拒绝(ORA-12520) - 推荐起始值:
RETRIES=3、DELAY=5(最多 15 秒不可用),再根据监控调整
FAILOVER_MODE 写对了位置,但 JDBC 没走 tnsnames 别名,或者 TNS_ADMIN 没生效**——这两者一错,前面所有配置都白搭。验证前先用 tnsping RACDB 确认别名可解析,再查应用进程的环境变量是否含 TNS_ADMIN。











