分布式事务基本概念可参考分布式事务介绍
这里我们介绍Atomikos分布式事务,它是基于XA的分布式事务
1、准备-创建数据库
在192.168.127.129和192.168.127.134分别创建数据库xa_129和xa_134, 表分别为xa_129, xa_134, 表结构都是id和name。
2、创建工程
1) 创建Spring Boot工程
命名为my-xa-demo
选择需要的依赖后点击完成
3、添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency>
4、使用MyBatis-generator生成数据库相关的文件
5、配置数据源
1) ConfigDb129
/** * 数据源配置。RM资源管理器 */ @Configuration @MapperScan(value = "com.example.myxademo.db129.dao", sqlSessionFactoryRef = "sqlSessionFactoryBean129") public class ConfigDb129 { @Bean("db129") public DataSource db129(){ MysqlXADataSource xaDs = new MysqlXADataSource(); xaDs.setUser("root"); xaDs.setPassword("123456"); xaDs.setUrl("jdbc:mysql://192.168.127.129:3306/xa_129"); AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean(); atomikosDataSourceBean.setXaDataSource(xaDs); atomikosDataSourceBean.setUniqueResourceName("db129"); return atomikosDataSourceBean; } @Bean("sqlSessionFactoryBean129") public SqlSessionFactoryBean sqlSessionFactoryBean(@Qualifier("db129") DataSource dataSource) throws IOException { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); sqlSessionFactoryBean.setMapperLocations(resourcePatternResolver.getResources("mybatis/db129/*.xml")); return sqlSessionFactoryBean; } /** * JTA 事务管理器 * @return */ @Bean("xaTransaction") public JtaTransactionManager jtaTransactionManager(){ UserTransaction userTransaction = new UserTransactionImp(); UserTransactionManager userTransactionManager = new UserTransactionManager(); return new JtaTransactionManager(userTransaction, userTransactionManager); } }
并且定义了事务管理器
ConfigDb134
/** * 数据源配置。RM资源管理器 */ @Configuration @MapperScan(value = "com.example.myxademo.db134.dao", sqlSessionFactoryRef = "sqlSessionFactoryBean134") public class ConfigDb134 { @Bean("db134") public DataSource db134(){ MysqlXADataSource xaDs = new MysqlXADataSource(); xaDs.setUser("root"); xaDs.setPassword("123456"); xaDs.setUrl("jdbc:mysql://192.168.127.134:3306/xa_134"); AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean(); atomikosDataSourceBean.setUniqueResourceName("db134"); atomikosDataSourceBean.setXaDataSource(xaDs); return atomikosDataSourceBean; } @Bean("sqlSessionFactoryBean134") public SqlSessionFactoryBean sqlSessionFactoryBean(@Qualifier("db134") DataSource dataSource) throws IOException { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); sqlSessionFactoryBean.setMapperLocations(resourcePatternResolver.getResources("mybatis/db134/*.xml")); return sqlSessionFactoryBean; } }
6、创建服务
@Service public class XAService { @Resource private XA129Mapper xa129Mapper; @Resource private XA134Mapper xa134Mapper; @Transactional(transactionManager = "xaTransaction") public void testXA(){ XA129 xa129 = new XA129(); xa129.setId(1); xa129.setName("XA_129"); xa129Mapper.insert(xa129); XA134 xa134 = new XA134(); xa134.setId(1); xa134.setName("XA_134"); xa134Mapper.insert(xa134); } }
7、测试
@SpringBootTest class MyXaDemoApplicationTests { @Test void testXA() { xaService.testXA(); } }
运行后,可以发现两个数据库多插入成功了。
8、模拟事务回滚
将两个表的数据清空,并且修改name字段的长度为1,重新运行测试
可以发现,两个表都没有插入成功。
最新评论