You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多数据源下基于Atomikos实现事务回滚的方案咨询

多数据源事务回滚方案(Atomikos及替代实现)

一、使用Atomikos实现强一致事务回滚

Atomikos是轻量级JTA事务管理器,可实现跨多数据源的分布式事务,确保任一数据源操作失败时全部回滚。

1. 引入依赖

Maven项目添加以下依赖:

<dependency>
    <groupId>com.atomikos</groupId>
    <artifactId>transactions-jta</artifactId>
    <version>4.0.6</version>
</dependency>
<dependency>
    <groupId>com.atomikos</groupId>
    <artifactId>transactions-jdbc</artifactId>
    <version>4.0.6</version>
</dependency>
<!-- 对应数据库的XA驱动,以MySQL为例 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
</dependency>

2. 配置XA数据源

将每个数据源包装为Atomikos兼容的XA数据源,示例为两个MySQL数据源:

@Configuration
public class DataSourceConfig {

    @Bean(name = "dataSource1")
    public DataSource dataSource1() {
        AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
        MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
        mysqlXaDataSource.setUrl("jdbc:mysql://localhost:3306/db1?useSSL=false");
        mysqlXaDataSource.setUser("root");
        mysqlXaDataSource.setPassword("password");

        xaDataSource.setXaDataSource(mysqlXaDataSource);
        xaDataSource.setUniqueResourceName("db1");
        xaDataSource.setMinPoolSize(5);
        xaDataSource.setMaxPoolSize(20);
        return xaDataSource;
    }

    @Bean(name = "dataSource2")
    public DataSource dataSource2() {
        AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
        MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
        mysqlXaDataSource.setUrl("jdbc:mysql://localhost:3306/db2?useSSL=false");
        mysqlXaDataSource.setUser("root");
        mysqlXaDataSource.setPassword("password");

        xaDataSource.setXaDataSource(mysqlXaDataSource);
        xaDataSource.setUniqueResourceName("db2");
        xaDataSource.setMinPoolSize(5);
        xaDataSource.setMaxPoolSize(20);
        return xaDataSource;
    }
}

3. 配置JTA事务管理器

适配Atomikos事务管理器与Spring的事务管理体系:

@Configuration
@EnableTransactionManagement
public class TransactionConfig {

    @Bean
    public UserTransaction userTransaction() throws SystemException {
        UserTransactionImp userTransactionImp = new UserTransactionImp();
        userTransactionImp.setTransactionTimeout(300);
        return userTransactionImp;
    }

    @Bean
    public UserTransactionManager atomikosTransactionManager() {
        UserTransactionManager userTransactionManager = new UserTransactionManager();
        userTransactionManager.setForceShutdown(false);
        return userTransactionManager;
    }

    @Bean(name = "jtaTransactionManager")
    public PlatformTransactionManager transactionManager(UserTransaction userTransaction, UserTransactionManager atomikosTransactionManager) {
        return new JtaTransactionManager(userTransaction, atomikosTransactionManager);
    }
}

4. 业务层使用事务

在业务方法上标注@Transactional并指定JTA事务管理器:

@Service
public class BizService {

    @Autowired
    private JdbcTemplate jdbcTemplate1; // 绑定dataSource1
    @Autowired
    private JdbcTemplate jdbcTemplate2; // 绑定dataSource2

    @Transactional(transactionManager = "jtaTransactionManager", rollbackFor = Exception.class)
    public void crossDataSourceOperation() throws Exception {
        // 操作第一个数据源
        jdbcTemplate1.update("INSERT INTO table1 (name) VALUES (?)", "test1");
        // 模拟第二个数据源操作失败
        if (true) {
            throw new RuntimeException("Second data source operation failed");
        }
        // 操作第二个数据源
        jdbcTemplate2.update("INSERT INTO table2 (name) VALUES (?)", "test2");
    }
}

此时若第二个操作抛出异常,两个数据源的插入操作都会被回滚。

二、替代方案

1. 使用Narayana作为JTA提供者

Narayana是开源JTA事务管理器,配置逻辑与Atomikos一致:

  • 引入Narayana依赖
  • 配置XA数据源
  • 适配Narayana事务管理器与Spring的JtaTransactionManager

2. Spring Boot原生JTA支持

Spring Boot默认集成JTA,只需引入对应依赖(如Atomikos/Narayana),并在application.yml配置XA数据源:

spring:
  jta:
    atomikos:
      datasource:
        db1:
          xa-data-source-class-name: com.mysql.cj.jdbc.MysqlXADataSource
          unique-resource-name: db1
          xa-properties:
            url: jdbc:mysql://localhost:3306/db1?useSSL=false
            user: root
            password: password
        db2:
          xa-data-source-class-name: com.mysql.cj.jdbc.MysqlXADataSource
          unique-resource-name: db2
          xa-properties:
            url: jdbc:mysql://localhost:3306/db2?useSSL=false
            user: root
            password: password

Spring Boot会自动配置JTA事务管理器,业务层直接使用@Transactional即可。

3. 最终一致性方案(非强一致)

若对性能要求高且可接受最终一致,可采用本地消息表+MQ方案:

  • 操作第一个数据源时,同步插入本地消息表
  • 第一个操作成功后,发送MQ消息触发第二个数据源操作
  • 若第二个操作失败,通过重试机制或人工补偿完成回滚/重试
  • 定期清理已完成的消息,确保数据最终一致

注意事项

  • 确保所有数据库支持XA协议(如MySQL需开启XA,部分轻量数据库可能不支持)
  • XA事务会增加系统开销,避免在高并发场景下滥用
  • 合理设置事务超时时间,避免长时间占用资源

内容的提问来源于stack exchange,提问作者Dharmin Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 04:45:25