欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringBoot+MyBatis+Atomikos(动态数据源/分布式事务XA)

程序员文章站 2022-05-23 12:55:43
...

快速集成工具,欢迎打脸

说明

适用环境:SpringBoot / MyBatis / Atomickos 
特性:

  1. 多数据源,动态切换
  2. 多数据源,XA分布式事务支持(需引入Atomickos) 

仅支持Mybatis,采用AbstractRoutingDataSource实现数据源动态切换。 引入Atomickos分布式事务,可支持多数据源动态切换分布式事务。

使用方法

引入jar包依赖 maven:

      <dependency>
        <groupId>com.tomz</groupId>
        <artifactId>xatomic</artifactId>
        <version>1.0.0</version>
      </dependency>

gradle:

implementation 'com.tomz:xatomic:1.0.0'

使用注解切换数据源@DynamicDataSource,可以放在类或者方法上。

  • 多数据源功能 
    配置文件示例:对于name属性,当数据源集合中存在name=default的数据源时,该数据源作为默认数据源 ,不加@DynamicDataSource默认使用该数据源,否则取集合中的第一个数据源作为默认数据源

      spring:
          datasources:
            - name: ds1
              type: com.zaxxer.hikari.HikariDataSource
              username: root
              password:
              driver-class-name: com.mysql.cj.jdbc.Driver
              jdbcUrl: jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&allowMultiQueries=true&&serverTimezone=GMT%2B8
            - name: ds2
              type: com.zaxxer.hikari.HikariDataSource
              username: root
              password:
              driver-class-name: com.mysql.cj.jdbc.Driver
              jdbcUrl: jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&allowMultiQueries=true&&serverTimezone=GMT%2B8
    
  • 多数据源XA分布式事务支持 
    引入: implementation 'org.springframework.boot:spring-boot-starter-jta-atomikos' 配置文件与多数据源配置文件相似,但是数据源类型type需要改为支持XA的数据源对象, 如:MysqlXADataSource,DruidXADataSource。 需要注意的是,对于DruidXADataSource,支持的MySql驱动类型当前只到8.0.11版本。

     spring:
         datasources:
           - name: ds1
             type: com.mysql.cj.jdbc.MysqlXADataSource
             databaseName: test01
             hostName: localhost
             user: root
             password:
             port: 8909
             url: jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&allowMultiQueries=true&&serverTimezone=GMT%2B8
           - name: ds2
             type: com.mysql.cj.jdbc.MysqlXADataSource
             databaseName: test01
             hostName: localhost
             user: root
             password:
             port: 8909
             url: jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&allowMultiQueries=true&&serverTimezone=GMT%2B8
    

    此外还可以对Atomickos做配置

     # JtaProperties
     spring.jta:
     #  logDir:
       transactionManagerId: myTxMgrId
       # AtomikosProperties
     #  atomikos:
     #    properties:
       # org.springframework.boot.jta.atomikos.AtomikosDataSourceBean 数据源连接池配置
       atomikos:
         datasource:
           poolSize: 5
           minPoolSize: 3
           maxPoolSize: 20
           borrowConnectionTimeout: 60
           reapTimeout: 300
           maxIdleTime: 60
           maintenanceInterval: 60
           loginTimeout: 60
           testQuery: select 1
    

    最后,需要在Configuration类上面使用MapperScan注解,如下:

     //factoryBean替换掉默认的MapperFactoryBean,实现Mapper映射到每个数据源。仅使用xa分布式事务支持才需要添加该注解,否则只用多数据源功能可以不加
     @MapperScan(factoryBean = XaDynamicMapperFactoryBean.class, basePackages = {"com.test.mapper"}) 
     @SpringBootApplication 
     class ApplicationDemo { 
        public static void main(String[] args) {
        		SpringApplication.run(ApplicationDemo.class, args);
        	}   
     }
     //mapper类
     @Mapper
     public interface TestMapper {  
         @DynamicDataSource("ds1")
         @Insert("insert into test(name) values ('a')")
         long insertA();
     
         @DynamicDataSource("ds2")
         @Insert("insert into test(name) values ('b')")
         long insertB();
     }
     //service类
     @Service
     class ServiceA {
           @Autowired
           private TestMapper mapper;
           @Transactional(rollbackFor = Exception.class)
           public void insertAB() {
               this.mapper.insertA();
               this.mapper.insertB();
               //throw new IllegalArgumentException("test xa-rollback");
           }
     }
     //测试类
     @RunWith(SpringRunner.class)
     @SpringBootTest
     public class ServiceTest {
     
         @Autowired
         private ServiceA service;
     
         @Test
         public void testXa() {
             this.service.insertAB();
         }
     
     }
    

    禁用分布式事务数据源:spring.jta.enabled=false 
    禁用动态多数据源:spring.dynamic.datasouce.enabled=false

    备注:该项目需要自己下载到本地,执行install安装到本地才能引用。????