Springboot+(XA协议2PC模式)JTA+Atomikos 处理分布式事务

本章先以单个项目演示 跨库事务处理,在上一章(多数据源)的基础上来扩展。

多数据源配置参考:https://www.jianshu.com/p/a8e602b41c27

1、新增 Maven依赖


            org.springframework.boot
            spring-boot-starter-jta-atomikos
            2.5.4
        

2、新增 yml配置

spring:
  jta:
    log-dir: tx-logs
    transaction-manager-id: txManager
    atomikos:
      properties:
        log-base-dir: ./double-sql-log

3、修改 多数据源代码配置

修改 数据源1 里面的 orderLogDateSource 方法的配置

    @ConfigurationProperties(prefix = "spring.datasource.order")
    @Primary
    public DataSource orderLogDateSource() throws SQLException {
//        return DataSourceBuilder.create().build();//如果没有分布式事务,这个就可以了

// 有了分布式事务,用下面的这个,这几个get的参数,就不粘贴了,就是把yml的配置读取出来而已
        MysqlXADataSource mysqlXADataSource = new MysqlXADataSource();
        mysqlXADataSource.setUrl(dateSourceProperties.getOrder().getJdbcUrl());
        mysqlXADataSource.setUser(dateSourceProperties.getOrder().getUsername());
        mysqlXADataSource.setPassword(dateSourceProperties.getOrder().getPassword());
        mysqlXADataSource.setPinGlobalTxToPhysicalConnection(true);

        // 将本地事务注册到创 Atomikos全局事务
        AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
        xaDataSource.setXaDataSource(mysqlXADataSource);
        xaDataSource.setUniqueResourceName("orderDataSource");
        return xaDataSource;
    }

再修改 数据源2 里面的 0方法的配置

    @Bean(name = "orderlogDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.orderlog")
    public DataSource orderDataSource() throws SQLException {
//        return DataSourceBuilder.create().build();//如果没有分布式事务,这个就可以了

        MysqlXADataSource mysqlXADataSource = new MysqlXADataSource();
        mysqlXADataSource.setUrl(dateSourceProperties.getOrderlog().getJdbcUrl());
        mysqlXADataSource.setUser(dateSourceProperties.getOrderlog().getUsername());
        mysqlXADataSource.setPassword(dateSourceProperties.getOrderlog().getPassword());
        mysqlXADataSource.setPinGlobalTxToPhysicalConnection(true);

        // 将本地事务注册到创 Atomikos全局事务
        AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
        xaDataSource.setXaDataSource(mysqlXADataSource);
        xaDataSource.setUniqueResourceName("orderlogDataSource");
        return xaDataSource;
    }

4、用法

@Slf4j
@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;// 数据源1
    @Autowired
    private OrderLogMapper orderLogMapper;// 数据源2

    // 新增完配置之后,使用起来就跟使用普通的事务注解一样
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void insert1() {
        log.info("【OrderService.insert1】 开始执行");
        String uuid = UUID.randomUUID().toString().replace("-", "").substring(10, 15);

        OrderEntity orderEntity = new OrderEntity("order" + uuid, "订单信息插入成功");
        orderMapper.insert1(orderEntity);
       int i = 10/0;//这里模式报错,就可以看到两个数据库各自的表中都没有数据插入
        System.out.println("**************************************************************");
        OrderLogEntity logEntity = new OrderLogEntity("log" + uuid, "订单日志插入成功");
        orderLogMapper.insert1(logEntity);

        System.out.println("完毕!");

    }

}

你可能感兴趣的:(Springboot+(XA协议2PC模式)JTA+Atomikos 处理分布式事务)