atomikos应用场景:单应用多数据源
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency> <!-- 这里不使用自动配置,所以不引入starter --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.14</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> 复制代码
spring: datasource: #使用druid连接池 druid: #数据源1的名称 one: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://192.168.211.128:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false username: root password: root #数据源2的名称 two: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://192.168.211.129:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false username: root password: root 复制代码
只需要配置数据源即可,全局事务管理器(JtaTransactionManager)由spring自动配置
@Configuration public class DataSourceConfig { /** * 创建Druid的XA连接池 * @return */ @Bean @ConfigurationProperties("spring.datasource.druid.one") public XADataSource druidXADataSource1(){ return new DruidXADataSource(); } /** * 创建Atomikos数据源 * 注解@DependsOn("druidXADataSource1"),在名为druidXADataSource1的bean实例化后加载当前bean * @param xaDataSource * @return */ @Bean @DependsOn("druidXADataSource1") @Primary public DataSource dataSource1(@Qualifier("druidXADataSource1") XADataSource xaDataSource) { //这里的AtomikosDataSourceBean使用的是spring提供的 AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean(); dataSource.setXaDataSource(xaDataSource); return dataSource; } @Bean @ConfigurationProperties("spring.datasource.druid.two") public XADataSource druidXADataSource2(){ return new DruidXADataSource(); } @Bean @DependsOn("druidXADataSource2") public DataSource dataSource2(@Qualifier("druidXADataSource2") XADataSource xaDataSource) { AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean(); dataSource.setXaDataSource(xaDataSource); return dataSource; } } 复制代码
如果使用其他的orm框架,自行配置。
数据源2的mybatis配置和下面代码相似,去除@Primary注解,修改配置属性即可。
@Configuration //指定扫描的dao包和SqlSession实例 @MapperScan(basePackages = "demo.springboot.atomikos.dao1", sqlSessionTemplateRef = "sessionTemplate1") public class Mybatis1Config { /** * SqlSessionFactory * * @param dataSource * @return * @throws Exception */ @Bean @Primary public SqlSessionFactory sqlSessionFactory1(@Qualifier("dataSource1") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); //mapper文件位置 // bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/one/*.xml")); return bean.getObject(); } /** * SqlSession实例 * * @param sqlSessionFactory * @return */ @Bean @Primary public SqlSessionTemplate sessionTemplate1(@Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } } 复制代码
public interface UserDAO1 { @Update("update user set name = #{name} where id = #{id}") int updateById(@Param("name")String name, @Param("id")Long id); } public interface UserDAO2 { @Update("update user set name = #{name} where id = #{id}") int updateById(@Param("name")String name, @Param("id")Long id); } 复制代码
@Service public class TestService { @Autowired private UserDAO1 userDAO1; @Autowired private UserDAO2 userDAO2; /** * 在需要事务的方法加上@Transactional注解即可 */ @Transactional public void test(){ userDAO1.updateById("haha", 1L); userDAO2.updateById("hehe", 2L); //模拟异常 int a = 1/0; } } 复制代码
@RunWith(SpringRunner.class) @SpringBootTest public class AtomikosApplicationTests { @Autowired private TestService testService; @Test public void test() { testService.test(); } } 复制代码
数据源1中的User{"id":1,"name":"张三"}
数据源2中的User{"id":2,name:"李四"}
运行测试出现异常后,两个数据库都回滚了,数据未改变
作者公众号