spring多数据源事务需用atomikos实现xa全局事务,替换默认事务管理器;各数据源须配置xa驱动、唯一资源名,并使用jtatransactionmanager,yaml中xa配置字段需符合规范。

Spring 默认的 @Transactional 只能管理单数据源本地事务,遇到多数据源(比如 PostgreSQL + SQL Server、或两个 MySQL 实例)时,必须借助 JTA 规范和 XA 协议,由 Atomikos 作为事务管理器统一协调——它不是“增强”Spring 事务,而是替换掉默认的事务机制,让所有参与的数据源真正纳入同一个全局事务生命周期。
关键配置:用 AtomikosDataSourceBean 替代普通数据源
不能继续使用 HikariDataSource 或 DruidDataSource,必须改用支持 XA 的包装类:
- 每个数据源需指定对应的 XA 驱动类,例如:
PostgreSQL →org.postgresql.xa.PGXADataSource
SQL Server →com.microsoft.sqlserver.jdbc.SQLServerXADataSource
MySQL 8+ →com.mysql.cj.jdbc.MysqlXADataSource - 为每个数据源设置唯一资源名(
setUniqueResourceName),如"pg_ds"和"sqlserver_ds",Atomikos 靠它识别和追踪参与者 - 连接池参数(如最小空闲、最大活跃数)需通过
AtomikosDataSourceBean设置,而非底层 XA 数据源本身
事务管理器必须是 JtaTransactionManager
Spring 不再使用 DataSourceTransactionManager,而要显式声明一个 JtaTransactionManager Bean,并注入 Atomikos 提供的 UserTransactionManager 和 UserTransaction:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 该管理器会拦截所有
@Transactional方法,自动绑定当前线程的全局事务上下文(XID) - 只要在同一个方法内操作多个 XA 数据源,它们获取的 Connection 就会被自动注册为同一事务的参与者
- 无需手动调用 begin/commit/rollback,完全由 Spring + Atomikos 联合驱动两阶段提交流程
YAML 配置要注意 XA 专属字段
application.yml 中不能沿用普通数据源写法,必须使用 xa: 嵌套块,并注意字段命名差异:
-
username要写成user(XA 协议要求) -
password保持不变 - 必须显式配置
data-source-class-name,否则 Atomikos 无法实例化 XA 驱动 - 示例片段:
spring:
datasource:
pg:
jdbc-url: jdbc:postgresql://localhost:5432/db1
user: pg_user
password: pg_pass
xa:
data-source-class-name: org.postgresql.xa.PGXADataSource
sqlserver:
jdbc-url: jdbc:sqlserver://localhost:1433;databaseName=db2
user: sa
password: sa_pass
xa:
data-source-class-name: com.microsoft.sqlserver.jdbc.SQLServerXADataSource
代码层只需标准 @Transactional,但有硬性前提
业务方法上加 @Transactional 即可,但必须满足以下条件,否则事务不会生效:
- 方法必须是 public,且被 Spring 容器代理调用(不能 this.xxx() 自调用)
- 所有 DAO 层操作必须通过 Spring 管理的
JdbcTemplate或SqlSessionTemplate(MyBatis)执行,不能直接 new Connection - 不能混用非 XA 数据源——哪怕只在一个方法里查一次普通 Hikari 连接,整个全局事务就会降级失效
- 异常必须传播出方法边界(不能被 try-catch 吞掉),否则 Atomikos 无法触发 rollback
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










