oracle 19c rac的taf未自动生效,主因是failover_mode未作为connect_data直接子项配置、java应用未通过tnsnames别名连接且未设置tns_admin、type与method配对错误(如select未配hold_cursors)、preconnect在ojdbc8+已废弃,或rac服务未正确注册监听。

不是RAC不支持自动故障转移,而是TAF(Transparent Application Failover)配置没生效——90%的问题出在FAILOVER_MODE位置写错或Java应用没走tnsnames别名。
FAILOVER_MODE必须紧贴CONNECT_DATA,放错位置等于没写
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别名连接,且TNS_ADMIN必须生效
JDBC Thin驱动(ojdbc8.jar或ojdbc11.jar)只在解析tnsnames.ora时读取FAILOVER_MODE。Easy Connect格式根本不会触发TAF。
- ❌ 错误写法:
jdbc:oracle:thin:@//rac1-vip:1521/orcl→ TAF不加载,故障时直接报ORA-03113 - ✅ 正确写法:
jdbc:oracle:thin:@RACDB(RACDB是tnsnames.ora里的别名) - 启动JVM前必须设置环境变量:
TNS_ADMIN=/path/to/tnsdir,指向含tnsnames.ora的目录 - Spring Boot里光靠
spring.datasource.url=jdbc:oracle:thin:@RACDB不够,还要确保JVM能读到TNS_ADMIN路径下的文件
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> - 检查服务是否注册到监听:
lsnrctl status里能看到该SERVICE_NAME对应多个实例 - 验证TAF是否生效:连接后查
v$session,failover_type和failover_method字段应非NONE - 服务配置漏掉备节点也会失效:
srvctl config service -d dbocs -s ocsdbsrv若只显示Preferred instances: dbocs1,没列Available instances,切换必然失败
真正容易被忽略的是:TAF不是开箱即用的功能,它需要客户端、网络配置、服务定义、JDBC行为四者严丝合缝。任何一个环节断链,故障时就会卡在IO Error: Connection reset或ORA-03113,而不是安静地切走。











