oracle必须用xa模式而非at模式,因at依赖sql解析与undo_log自动生成,而oracle不支持该机制;强行使用会导致分支注册成功但全局提交卡死在phaseone,且ojdbc8+驱动对sql拦截敏感,易触发协议异常;xa模式则交由oracle自身xa实现完成两阶段提交,是唯一官方验证路径。

Oracle 在 Seata 中不能用 AT 模式,必须走 XA 模式,否则 GlobalTransaction 会静默失败或抛 XAException,日志里几乎不暴露根本原因。
为什么 Oracle 必须用 XA 模式而不是 AT 模式
AT 模式依赖数据库层解析 SQL 并自动生成 undo_log 表回滚快照,但 Oracle 不支持该机制——它没有标准的 SELECT FOR UPDATE + INSERT INTO undo_log 兼容路径。强行启用会导致分支事务注册成功、全局提交卡死在 PhaseOne,现象是服务无响应、TC 日志停在 “branch register success” 后不再推进。
AT 模式下 Seata 会尝试拦截并重写 SQL,Oracle 驱动(尤其是 ojdbc8+)对此行为敏感,容易触发协议异常或隐式连接关闭。
XA 模式把事务控制权交还给 Oracle 自身的 XA 实现,由 OracleXADataSource 和底层 XAResource 协同完成两阶段提交,这是唯一被 Oracle 官方验证的分布式事务路径。
Spring Boot 3.x 中如何正确配置 Oracle XA 数据源
Spring Boot 3.x 的 spring-boot-starter-jdbc 自动配置会覆盖 XA 数据源初始化逻辑,必须显式禁用:
- 在
application.yml中添加:spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration - 使用
ojdbc8.jar(对应 Oracle 12.1+),搭配oracle.jdbc.xa.client.OracleXADataSource;ojdbc6.jar未实现XAResource接口,RM 注册直接失败 - URL 必须含
tns_alias或完整格式:jdbc:oracle:thin:@//host:port/service_name,不能用旧式@host:port:sid,否则 XA 连接无法识别为 XA-capable
Seata 客户端必须关闭 AT 并强制启用 XA 模式
仅改数据源类型不够,Seata 配置中必须明确切断 AT 路径:
-
seata.data-source-proxy-mode: XA(注意不是AT,也不是空值) -
file.conf中确保store.mode="db"(XA 模式仍需 TC 存储事务状态),且service.vgroupMapping.my_test_tx_group="default"与应用侧一致 -
client.rm.report.success.enable=false:Oracle XA 分支的commit/rollback由数据库自身驱动完成,Seata RM 不应上报“成功”,否则 TC 可能提前释放 XID 锁
Oracle 数据库端必须开启 XA 支持并授予权限
Java 层配置全对,Oracle 实例若未启用 XA,连接会在 prepare 阶段直接拒绝,错误日志只显示 java.sql.SQLException: Protocol violation,无有效线索。
需在数据库中执行:
-
ALTER SYSTEM SET "_xa_roundtrip_optimization"=false SCOPE=BOTH;(Oracle 12c+ 必须关闭,否则 XA 分支prepare失败) GRANT SELECT ON sys.dba_pending_transactions TO your_user;GRANT SELECT ON sys.pending_trans$ TO your_user;GRANT FORCE ANY TRANSACTION TO your_user;
最容易被忽略的是 "_xa_roundtrip_optimization" 参数,它默认开启,但会使 Oracle XA 分支在 prepare 阶段返回协议错误,且不报具体原因。











