分布式事务-基于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.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("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