Spring Boot 3.x 中用 Atomikos 处理 Oracle 跨库事务,必须使用 oracle.jdbc.xa.client.OracleXADataSource 驱动(ojdbc8 21.10+),正确配置 xa-properties、UniqueResourceName、JtaTransactionManager Bean 及事务日志路径,并确保 Oracle 端 undo_retention ≥ 3600。
spring boot 3.x 中用 atomikos 处理 oracle 跨库事务,必须用 oracle.jdbc.xa.client.oraclexadatasource,且驱动版本不能低于 21c(ojdbc8 21.10+),否则 xa_start 会报 ora-01010 错误。
Oracle XA 驱动必须显式启用并验证支持
Oracle 官方对 XA 的支持有严格版本约束:ojdbc8 19.3+ 才开始稳定支持 OracleXADataSource,但真正修复 xa_forget 和两阶段提交日志恢复问题的是 21.10+。很多团队踩坑在用 ojdbc8 19.6 连接 Oracle 23ai,结果事务挂起后无法自动恢复。
- 检查驱动是否真支持 XA:
SELECT * FROM V$VERSION确认数据库版本;再运行java -cp ojdbc8.jar oracle.jdbc.driver.OracleDriver看是否抛出ClassNotFoundException: oracle.jdbc.xa.client.OracleXADataSource - 必须在 JDBC URL 中添加
oracle.net.disableOob=true,否则 Oracle 12c+ 在高并发下可能触发 OOB(out-of-band)中断导致 XA prepare 失败 - 连接池不能复用非 XA 连接:
AtomikosDataSourceBean必须直接包装OracleXADataSource,不能套 Druid 或 Hikari 的 XA 封装类——它们会绕过 Atomikos 的 XAResource 注册逻辑
application.yml 中的 xa-properties 写法极易出错
Oracle 的 XA 属性名和 MySQL/PostgreSQL 不同,URL、user、password 是无效键,必须用 Oracle 原生属性名,否则 OracleXADataSource.setURL() 不会被调用,连接时抛 ORA-17067: invalid URL。
- 正确写法是:
xa-properties: URL: jdbc:oracle:thin:@//host:1521/ORCLPDB1;User: scott;Password: tiger;oracle.net.disableOob: "true" -
UniqueResourceName必须全局唯一且不含特殊字符(如点、下划线),建议用小写字母+数字组合,例如oracledb1,否则 Atomikos 日志中会出现duplicate resource name导致第二个数据源注册失败 - Oracle 不支持
min-pool-size自动预热,必须设pool-size-min: 1并配test-query: SELECT 1 FROM DUAL,否则首次事务会卡在连接创建上
@Transactional 生效的前提是 DataSource 和 JtaTransactionManager 绑定正确
Spring Boot 3.x 默认不再自动配置 JtaTransactionManager,仅靠 spring-boot-starter-jta-atomikos 不够——它只注册 UserTransaction 和 TransactionManager bean,但不会替换 Spring 的事务管理器。
- 必须手动声明
@Bean类型为JtaTransactionManager,且构造参数传入UserTransaction和TransactionManager - 所有
@Service方法上的@Transactional必须标注transactionManager = "jtaTransactionManager",否则走的是默认的DataSourceTransactionManager,只对单库生效 - Oracle 要求每个 XA 分支的
Xid全局唯一,Atomikos 默认用com.atomikos.icatch.max_actives控制并发事务数,若跨库操作频繁,需在jta.properties中调大该值,否则出现no more transactions available
XA 事务日志路径和权限常被忽略
Atomikos 默认把事务日志写到 ./transaction_logs,但在容器或 Linux 生产环境,该路径可能不可写,或被 SELinux 拦截,导致 prepare 成功但 commit 时静默失败。
- 务必在
application.yml显式配置:spring.jta.atomikos.properties.com.atomikos.icatch.log-base-dir: /var/log/atomikos - 目录需赋予运行用户读写权限,且不能是 tmpfs 或 NFS 挂载点(XA 日志要求 fsync 级持久化)
- Oracle 数据库端也要确认
undo_retention≥ 3600,否则 XA 事务长时间挂起后,Oracle 可能提前清理 undo segment,造成 recovery 失败



















