Oracle TAF 在 JDBC 中仅通过连接串启用,需 ojdbc8+ 驱动、服务端配置 FAILOVER_TYPE=SELECT,并在连接串中同时设置 FAILOVER=true 和完整 FAILOVER_MODE=(TYPE=select)(METHOD=basic)(RETRIES=n)(DELAY=n)。
Oracle TAF 在 JDBC 连接串里怎么开
java 端启用 taf 不靠代码逻辑,只靠连接串参数和驱动版本。jdbc 驱动必须是 ojdbc8.jar(或更高)且服务端已配置 taf(比如 rac 的 service 启用了 failover_type=select),否则客户端加再多参数也无效。
关键参数就两个:FAILOVER=true 和 FAILOVER_MODE=(TYPE=select)(METHOD=basic)(RETRIES=5)(DELAY=2),必须一起出现,缺一不可。
-
FAILOVER=true是开关,不设它,后面整个FAILOVER_MODE被忽略 -
TYPE=select表示支持会话级 SELECT 语句自动重连并续跑(DML 不支持,会报ORA-25402: transaction must roll back) -
METHOD=basic是唯一被 ojdbc8 支持的模式;preconnect已废弃,设了也不生效 -
RETRIES和DELAY控制重试节奏,但实际重试由 Oracle Net 层接管,JDBC 层看不到中间过程
完整连接串示例:jdbc:oracle:thin:@(DESCRIPTION=(FAILOVER=true)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=rac1)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=rac2)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=myapp)(FAILOVER_MODE=(TYPE=select)(METHOD=basic)(RETRIES=3)(DELAY=1))))
为什么 setFailoverEnabled(true) 没用
这是最容易踩的坑:JDBC OracleDataSource 提供的 setFailoverEnabled(true) 方法在 ojdbc8+ 中已被标记为 @Deprecated,调用它不会触发任何 TAF 行为,也不会报错,纯属静默失效。
原因很简单:TAF 是 Oracle Net 层特性,不是 JDBC 驱动自己实现的故障转移逻辑。驱动只负责把连接串里的 FAILOVER 参数透传给 Oracle Net Client(即底层 oci.dll 或 thin 模式内置的等效逻辑)。
立即学习“Java免费学习笔记(深入)”;
- thin 模式下,TAF 完全依赖连接串参数,代码里任何 setter 都无效
- oci 模式(需本地 Oracle Client)同样只认连接串,且要求
sqlnet.ora里有FAILOVER=ON - 如果你看到旧文档写“调用 setFailoverEnabled”,说明它针对的是 10g 时代的 ojdbc14,早已过时
TAF 生效时应用会收到什么异常
TAF 不是“无感切换”。连接断开瞬间,正在执行的语句会抛出明确异常,应用必须捕获并处理——否则线程直接挂掉,TAF 就没意义了。
典型错误包括:SQLException 带 SQLState 08006(connection exception)或 Oracle 错误码 ORA-03113、ORA-03114、ORA-1012。只要连接串配置正确,这些异常之后,后续 executeQuery() 会自动在新节点上继续执行(仅限 TYPE=select 场景)。
- SELECT 语句中断后重发,结果集从头开始,游标位置丢失(TAF 不保存 fetch position)
- UPDATE/INSERT/DELETE 中断必然失败,必须显式 rollback + 重试业务逻辑,TAF 不帮你续 DML
- 如果连接串漏了
FAILOVER_MODE,哪怕只抛ORA-03113,后续操作也会直接报closed connection,不会重连
验证 TAF 是否真生效的最小检查点
别信连接成功就万事大吉。真正验证得看“故障发生时行为是否符合预期”,最简方式是手动 kill 一个 RAC 实例的 PMON 进程(或停掉对应节点的监听),然后观察应用日志。
- 看到连续两次
SQLException(第一次断连,第二次重连成功)说明 TAF 启动了 - SELECT 查询没报
ORA-25402且返回了结果,说明TYPE=select生效 - 如果只报一次异常就永远卡住,检查连接串是否漏了
FAILOVER=true或驱动版本太低 - 注意:单实例数据库即使配了 TAF 参数,failover 也永远不会触发,因为没其他节点可切
复杂点在于 TAF 依赖 Oracle Net 的底层状态同步,而这个过程对 Java 应用层完全透明。你控制不了细节,只能确保参数、驱动、服务端三者对齐——少一个,就只是个普通连接串。











