failover_mode必须作为connect_data的直接子项,否则oracle net静默忽略;java应用须用tnsnames别名连接并设置tns_admin,type与method需配对(如session+basic),否则taf不生效。

tnsnames.ora里FAILOVER_MODE位置写错,TAF直接失效
Oracle Net只认一种结构:FAILOVER_MODE必须作为CONNECT_DATA的直接子项,放错位置等于没写,驱动静默跳过,连日志都不报错。
- ✅ 正确写法:
(CONNECT_DATA = (SERVICE_NAME = mypdb) (FAILOVER_MODE = (TYPE = SESSION) (METHOD = BASIC))) - ❌ 错误写法1:
(DESCRIPTION = (FAILOVER_MODE = ...) (ADDRESS_LIST = ...))—— 参数被完全忽略 - ❌ 错误写法2:
(ADDRESS_LIST = (FAILOVER_MODE = ...) (ADDRESS = ...))—— 同样无效 - 常见误配:把
FAILOVER_MODE塞进ADDRESS块、或提级到DESCRIPTION顶层,结果TAF形同虚设
Java应用没走tnsnames别名,TAF压根不加载
JDBC Thin驱动(ojdbc8.jar或ojdbc11.jar)只在解析tnsnames.ora时读取FAILOVER_MODE。Easy Connect格式(如jdbc:oracle:thin:@//rac1-vip:1521/orcl)根本不会触发TAF。
- 必须用tnsnames别名连接:
jdbc:oracle:thin:@RACDB,不能直写IP/SCAN/VIP - 启动Java进程前,必须设置
TNS_ADMIN环境变量,指向含tnsnames.ora的目录 - Spring Boot中仅靠
spring.datasource.url=jdbc:oracle:thin:@RACDB不够,还需确保TNS_ADMIN生效,且JVM能读到该文件 - 验证方式:连接后查
v$session,failover_type和failover_method字段应非NONE
TYPE与METHOD配对错误,故障时反而中断会话
TYPE决定“故障后做什么”,METHOD决定“什么时候做”。两者不匹配会导致查询失败、事务丢失,而不是自动续查。
-
TYPE = SESSION+METHOD = BASIC:最稳组合。实例宕机后重建新会话,SELECT自动重执行,适合DML场景 -
TYPE = SELECT不是“更强”——它只对已打开游标有效,且需JDBC显式设置ResultSet.HOLD_CURSORS_OVER_COMMIT,否则照样抛ORA-03113 -
METHOD = PRECONNECT在ojdbc8+已废弃,设了也不生效,还可能触发ORA-12519(连接数超限) - 别乱设
RETRIES和DELAY:例如RETRIES=180、DELAY=5→ 最长等15分钟才放弃,但HTTP接口通常30秒就超时返回504
RAC服务没启用或未注册到监听,TAF无从谈起
TAF依赖底层服务可用。如果srvctl管理的服务没启、没注册到监听,客户端连都连不上,更别说故障转移。
- 确认服务已创建并启动:
srvctl add service -d <db_name> -s <service_name> -r <inst1>,<inst2></inst2></inst1></service_name></db_name>,再srvctl start service - 检查服务是否注册到监听:
lsnrctl status输出中应有该SERVICE_NAME,状态为READY - 若未注册,手工触发注册:
sqlplus / as sysdba执行alter system register - 验证服务状态:
crsctl stat res -t | grep <service_name></service_name>,确保状态为ONLINE且托管节点正确
FAILOVER_MODE必须嵌套在CONNECT_DATA里——这个层级关系错一格,整个机制就失效,而Oracle Net连警告都不打。











