1. 程式人生 > 其它 >分散式事務-基於XA協議的兩階段提交

分散式事務-基於XA協議的兩階段提交

分散式事務-基於XA協議的兩階段提交

XA協議是由X/OPen組織提出的分散式規範,mysql5.7以上版本均支援XA協議

由一個事務管理器(TM)和多個資源管理器組成(RM)

提交分為兩個階段 prepare和commit,保證事務的強一致性

缺點:效率比較低 比本地事務的相差10倍以上

在config中配置兩個XA資料來源,配置@MapperScan掃描不同的包

// ConfigDB1
@Configuration
@MapperScan(value = "com.alex.demo.db1.dao", sqlSessionFactoryRef = "db1SqlSessionFactoryBean"
) public class ConfigDB1 { @Bean("db1DataSource") public DataSource db1DataSource(){ // 使用基於XA協議的Atomikos資料來源 mysql5.7和8.0 以上的版本都支援 MysqlXADataSource xaDataSource = new MysqlXADataSource(); xaDataSource.setUser("root"); xaDataSource.setPassword
("123456"); xaDataSource.setUrl("jdbc:mysql://192.168.1.4:3310/xa"); AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean(); atomikosDataSourceBean.setXaDataSource(xaDataSource); return atomikosDataSourceBean; } @Bean("db1SqlSessionFactoryBean"
) public SqlSessionFactoryBean sqlSessionFactoryBean(@Qualifier("db1DataSource") DataSource dataSource) throws IOException { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); sqlSessionFactoryBean.setMapperLocations(resourceResolver.getResources("mybatis/db1/*.xml")); return sqlSessionFactoryBean; } } //ConfigDB2 @Configuration @MapperScan(value = "com.alex.demo.db2.dao",sqlSessionFactoryRef = "db2SqlSessionFactoryBean") public class ConfigDB2 { @Bean("db2DataSource") public DataSource db2DataSource(){ // 使用基於XA協議的Atomikos資料來源 mysql5.78.0 以上的版本都支援 MysqlXADataSource xaDataSource = new MysqlXADataSource(); xaDataSource.setUser("root"); xaDataSource.setPassword("123456"); xaDataSource.setUrl("jdbc:mysql://192.168.1.4:3310/xa"); AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean(); atomikosDataSourceBean.setXaDataSource(xaDataSource); return atomikosDataSourceBean; } @Bean("db2SqlSessionFactoryBean") public SqlSessionFactoryBean sqlSessionFactoryBean(@Qualifier("db2DataSource") DataSource dataSource) throws IOException { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); sqlSessionFactoryBean.setMapperLocations(resourceResolver.getResources("mybatis/db2/*.xml")); return sqlSessionFactoryBean; } }

配置基於XA協議的事務管理器

@Configuration
public class ConfigXATransaction {
    //建立基於XA協議的事務管理器
    @Bean("xaTransaction")
    public JtaTransactionManager jtaTransactionManager(){
        UserTransaction userTransaction = new UserTransactionImp();
        UserTransactionManager userTransactionManager = new UserTransactionManager();
        return new JtaTransactionManager(userTransaction,userTransactionManager);
    }
}

在service層配置基於XA協議的事務管理器

@Service
public class XAService {

    @Resource
    private XADB1Mapper XADB1Mapper;

    @Resource
    private XADB2Mapper XADB2Mapper;

    // 事務管理器配置
    @Transactional(transactionManager = "xaTransaction")
    public void testXA() {
        XADB1 XADB1 = new XADB1();
        XADB1.setId(2);
        XADB1.setName("xa_db1");
        XADB1Mapper.insert(XADB1);
        // 在此處會拋異常,兩條事務都會回滾
        int i = 1/0;
        XADB2 XADB2 = new XADB2();
        XADB2.setId(2);
        XADB2.setName("xa_db2");
        XADB2Mapper.insert(XADB2);
    }
}

原始碼地址 https://gitee.com/kakalex/xaDemo