Seata默认AT模式不支持Oracle,必须显式启用XA模式并配置匹配版本的Oracle原生XA数据源(如ojdbc8 + OracleXADataSource),否则GlobalTransaction会静默失败或抛XAException;需关闭AT相关机制、禁用自动配置、设置seata.data-source-proxy-mode: XA,并确保Oracle数据库端开启XA支持及权限。
seata 默认的 at 模式不支持 oracle xa,必须显式切换为 xa 模式并配置 oracle 原生 xa 数据源,否则 globaltransaction 会静默失败或抛出 xaexception,且日志中几乎不提示根本原因。
Oracle 驱动与 XA 数据源必须严格匹配版本
Oracle 12c/19c/21c 对应的 XA 实现类和驱动行为差异极大。用错会导致 ORA-01017(用户名密码错误)或更隐蔽的 XAER_RMFAIL 错误,实际是连接未被识别为 XA-capable。
- Oracle 12.1+ 推荐使用
ojdbc8.jar,对应oracle.jdbc.xa.client.OracleXADataSource - 不要混用
ojdbc6.jar+OracleXADataSource:JDBC 驱动未实现XAResource接口,RM 注册直接失败 - Spring Boot 3.x 环境下,
spring-boot-starter-jdbc的自动配置会干扰 XA 数据源初始化,需显式禁用:spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
Seata 配置文件中必须关闭 AT 模式并启用 XA
仅改数据源类型不够,seata.conf 和应用侧的 registry.conf 都要确认 TC 不再尝试解析 SQL 生成 undo_log —— Oracle 不支持该机制,强行启用会导致分支事务注册成功但全局提交时卡死在 PhaseOne。
-
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 锁 - 应用
application.yml中明确指定模式:seata.data-source-proxy-mode: XA(注意不是AT)
Oracle 数据库端需开放 XA 相关权限与参数
即使 Java 层配置全对,Oracle 实例若未启用 XA 支持,连接会在 prepare 阶段直接拒绝,错误日志只显示 java.sql.SQLException: Protocol violation,无有效线索。
- 执行 SQL 开启 XA:
ALTER SYSTEM SET "_xa_roundtrip_optimization"=false SCOPE=BOTH;(12c+ 必须关闭该优化,否则 XA 分支 prepare 失败) - 赋予用户权限:
GRANT SELECT ON sys.dba_pending_transactions TO your_user;、GRANT SELECT ON sys.pending_trans$ TO your_user;、GRANT SELECT ON sys.dba_2pc_pending TO your_user; - 确认数据库已启用分布式事务:
SELECT * FROM v$option WHERE parameter = 'Distributed Transaction';返回TRUE
XA 模式下事务传播与异常处理极易出错
Oracle XA 要求每个分支事务的 Xid 必须由同一个 TM(Seata TC)统一分配并全程透传,任何手动 new Xid、跨线程丢失上下文、或在非 Spring 管理的线程池中开启事务,都会导致分支无法关联到全局 XID,最终出现部分提交、部分回滚的脏状态。
- 避免在
@Async方法中调用@GlobalTransactional:默认线程池不传递 Seata 上下文,需自定义TaskDecorator注入RootContext - 捕获
CannotRegisterXAResourceException或XAException.XAER_RMERR后,必须立即终止当前方法,不能尝试重试或 fallback —— XA 协议下重复注册同一 Xid 会导致数据库挂起 - Oracle 的
rollback force 'xid_string'手动清理残留事务前,务必先查select * from dba_2pc_pending,否则可能误删其他服务的事务
XA 模式本质是把事务协调权交还给 Oracle 和 Seata TC,中间任何一环(驱动、数据源、TC 配置、DB 参数、线程上下文)断开,都不会报明确错误,而是表现为“看起来成功了但数据没提交”或“卡住不动”。最稳妥的做法是:先用最简 demo(单服务 + 单表 + 一个 INSERT)跑通全流程,再逐步加复杂度。











