.NET应用实现Oracle自动故障转移需协同Oracle Net配置、TAF服务端设置和客户端驱动行为三者;仅连接字符串加备用地址无效,必须tnsnames.ora中同时设LOAD_BALANCE=YES与FAILOVER=YES,.NET连接字符串启用Failover=true,且TAF服务须动态绑定PRIMARY角色。
不能只靠连接字符串加个备用地址就实现自动故障转移——.net 应用必须配合 oracle net 配置、taf 服务端设置和客户端驱动行为三者协同,否则 failover 后连接仍会卡死或报 ora-12154 / ora-12514。
tnsnames.ora 中 ADDRESS_LIST + LOAD_BALANCE 不等于故障转移
很多人以为在 .NET 的连接字符串里写上两个地址(主+备),再配 LOAD_BALANCE=YES 就能“自动切”,实际不是:
- 它只管「首次建连」时随机选一个地址尝试,失败后换下一个——但仅限于 connect-time 阶段;一旦连接建立成功,后续所有 SQL 请求都固定发往该实例,主库宕机后现有连接不会自动重连备库
-
LOAD_BALANCE=YES和FAILOVER=YES必须同时存在才启用连接时故障转移;缺一不可 - 如果主库监听还在但数据库已 hang(比如
ORACLE_HOME进程全死但 listener 没关),Oracle Net 可能连不上也判不断,超时由SQLNET.OUTBOUND_CONNECT_TIMEOUT控制,默认是 60 秒,太长会拖慢应用响应
正确示例(tnsnames.ora):
JED_RW =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = orarac)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = oraracdg)(PORT = 1521))
(LOAD_BALANCE = YES)
(FAILOVER = YES)
)
(CONNECT_DATA =
(SERVICE_NAME = JED_RW)
(FAILOVER_MODE =
(TYPE = SELECT)
(METHOD = BASIC)
(RETRIES = 3)
(DELAY = 5)
)
)
)
.NET 客户端必须显式启用 TAF,且驱动版本不能低于 12.1
Oracle Data Provider for .NET(ODP.NET)默认不启用 TAF,即使 tns 配置了 FAILOVER_MODE,也要在连接字符串中加开关:
- 使用
OracleConnection时,必须在连接字符串中包含Failover=true(注意:不是FAILOVER=TRUE,大小写敏感且键名不同) - 旧版 ODP.NET(如 11.2)不支持
TYPE=SELECT的透明重执行,只能做到 session 重建,select 结果丢失;12.1+ 才真正支持查询续跑 - 若用 Entity Framework,需确认其底层调用的 ODP.NET 版本,并在
app.config或connectionStrings中显式声明Failover=true
示例连接字符串(.NET):
Data Source=JED_RW;User Id=scott;Password=tiger;Failover=true;
TAF 服务必须在数据库端动态绑定到 PRIMARY 角色
光有客户端配置没用——服务名 JED_RW 必须只在主库上运行,且角色切换后自动启停,否则备库升主后该服务根本不存在,ORA-12514 直接报错:
- 服务创建语句中
failover_method => 'BASIC'和failover_type => 'SELECT'是硬性要求,不能用NONE - 触发器
cmc_taf_service_trg_rolechange必须监听db_role_change事件,不能只靠 startup 触发器;否则 switchover 后服务没切过来 - 检查服务是否真在运行:
SELECT NAME, NETWORK_NAME, STATUS FROM DBA_SERVICES WHERE NAME = 'JED_RW';—— 升主后 STATUS 应为RUNNING,且只在新主库上出现
FSFO observer 不参与 .NET 故障转移流程,别混为一谈
Fast-Start Failover 是 Data Guard Broker 管理的数据库层自动接管机制,和 .NET 应用完全无关:
- observer 进程只负责监控主库存活、触发
FAILOVER命令、更新 Broker 配置;它不改 VIP、不重启监听、不通知客户端 - .NET 应用感知不到 FSFO 是否发生,它只依赖 Oracle Net 层的连接重试逻辑 + TAF 服务是否存在
- 如果用了 VIP + keepalived,那 VIP 漂移才是应用“无感切换”的关键;但 VIP 漂移本身不解决 TAF 服务未启动、监听未注册等问题
最常被忽略的一点:FSFO 成功后,原主库控制文件里的 activation# 和新主库冲突,此时若误启原主库,哪怕只是 MOUNT,也会导致新主库监听拒绝新连接(报 ORA-16664),整个 TAF 流程彻底失效。


















