分布式系统-分布式事务05(springboot+atomiks

作者: 小亮__ | 来源:发表于2019-07-09 06:53 被阅读69次

    springboot 项目在使用分布式事务开源框架,atomiks

    pom

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>org.springframework.boot</artifactId>
    </dependency>
    

    application.properties(双数据源配置)

    # Mysql 1
    mysql.datasource.test1.url = jdbc:mysql://192.168.25.11:3306/18-08-12-manyDatasource1?useUnicode=true&characterEncoding=utf-8
    mysql.datasource.test1.username = root
    mysql.datasource.test1.password = @sS19980713
    mysql.datasource.test1.minPoolSize = 3
    mysql.datasource.test1.maxPoolSize = 25
    mysql.datasource.test1.maxLifetime = 20000
    mysql.datasource.test1.borrowConnectionTimeout = 30
    mysql.datasource.test1.loginTimeout = 30
    mysql.datasource.test1.maintenanceInterval = 60
    mysql.datasource.test1.maxIdleTime = 60
     
    # Mysql 2
    mysql.datasource.test2.url =jdbc:mysql://192.168.25.11:3306/18-08-12-manyDatasource2?useUnicode=true&characterEncoding=utf-8
    mysql.datasource.test2.username =root
    mysql.datasource.test2.password =@sS19980713
    mysql.datasource.test2.minPoolSize = 3
    mysql.datasource.test2.maxPoolSize = 25
    mysql.datasource.test2.maxLifetime = 20000
    mysql.datasource.test2.borrowConnectionTimeout = 30
    mysql.datasource.test2.loginTimeout = 30
    mysql.datasource.test2.maintenanceInterval = 60
    mysql.datasource.test2.maxIdleTime = 60
    

    创建配置bean对象

    /**
     * 将application.properties配置文件中配置自动封装到实体类字段中
     * @author Administrator
     */
    @Data
    @ConfigurationProperties(prefix = "mysql.datasource.test1") // 注意这个前缀要和application.properties文件的前缀一样
    public class DBConfig1 {
        private String url;
        // 比如这个url在properties中是这样子的mysql.datasource.test1.username = root
        private String username;
        private String password;
        private int minPoolSize;
        private int maxPoolSize;
        private int maxLifetime;
        private int borrowConnectionTimeout;
        private int loginTimeout;
        private int maintenanceInterval;
        private int maxIdleTime;
        private String testQuery;
    }
    
    /**
     * 将application.properties配置文件中配置自动封装到实体类字段中
     * @author Administrator
     */
    @Data
    @ConfigurationProperties(prefix = "mysql.datasource.test2")// 注意这个前缀要和application.properties文件的前缀一样
    public class DBConfig2 {
        private String url;
        // 比如这个url在properties中是这样子的mysql.datasource.test1.username = root
        private String username;
        private String password;
        private int minPoolSize;
        private int maxPoolSize;
        private int maxLifetime;
        private int borrowConnectionTimeout;
        private int loginTimeout;
        private int maintenanceInterval;
        private int maxIdleTime;
        private String testQuery;
    }
    
    

    创建Datasource,SqlSessionFactory,SqlSessionTemplate等对象

    
    @Configuration
    // basePackages 最好分开配置 如果放在同一个文件夹可能会报错
    @MapperScan(basePackages = "czs.mapper1", sqlSessionTemplateRef = "testSqlSessionTemplate")
    public class MyBatisConfig1 {
     
        // 配置数据源
        @Bean(name = "testDataSource")
        public DataSource testDataSource(DBConfig1 testConfig) throws SQLException {
            MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
            mysqlXaDataSource.setUrl(testConfig.getUrl());
            mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
            mysqlXaDataSource.setPassword(testConfig.getPassword());
            mysqlXaDataSource.setUser(testConfig.getUsername());
            mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
     
            // 将本地事务注册到创 Atomikos全局事务
            AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
            xaDataSource.setXaDataSource(mysqlXaDataSource);
            xaDataSource.setUniqueResourceName("testDataSource");
     
            xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
            xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
            xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
            xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
            xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
            xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
            xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
            xaDataSource.setTestQuery(testConfig.getTestQuery());
            return xaDataSource;
        }
     
        @Bean(name = "testSqlSessionFactory")
        public SqlSessionFactory testSqlSessionFactory(@Qualifier("testDataSource") DataSource dataSource)
                throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            return bean.getObject();
        }
     
        @Bean(name = "testSqlSessionTemplate")
        public SqlSessionTemplate testSqlSessionTemplate(
                @Qualifier("testSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    
    @Configuration
    @MapperScan(basePackages = "czs.mapper2", sqlSessionTemplateRef = "test2SqlSessionTemplate")
    public class MyBatisConfig2 {
     
        // 配置数据源
        @Bean(name = "test2DataSource")
        public DataSource testDataSource(DBConfig2 testConfig) throws SQLException {
            MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
            mysqlXaDataSource.setUrl(testConfig.getUrl());
            mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
            mysqlXaDataSource.setPassword(testConfig.getPassword());
            mysqlXaDataSource.setUser(testConfig.getUsername());
            mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
     
            AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
            xaDataSource.setXaDataSource(mysqlXaDataSource);
            xaDataSource.setUniqueResourceName("test2DataSource");
     
            xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
            xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
            xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
            xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
            xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
            xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
            xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
            xaDataSource.setTestQuery(testConfig.getTestQuery());
            return xaDataSource;
        }
     
        @Bean(name = "test2SqlSessionFactory")
        public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource)
                throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            return bean.getObject();
        }
     
        @Bean(name = "test2SqlSessionTemplate")
        public SqlSessionTemplate testSqlSessionTemplate(
                @Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    

    使用mybaties,不同的扫描路径使用不同的sqlsessionTemplate

    @MapperScan(basePackages = "czs.mapper1", sqlSessionTemplateRef = "test1SqlSessionTemplate")
    @MapperScan(basePackages = "czs.mapper2", sqlSessionTemplateRef = "test2SqlSessionTemplate")
    

    在service中使用

    @Service
    public class ManyService1 {
     
        @Autowired
        private UserMapper1 userMapper1;
     
        @Autowired
        private UserMapper2 userMapper2;
     
        // 开启事务,由于使用jta+atomikos解决分布式事务,所以此处不必再指定事务
        @Transactional
        public int insert(String name, Integer age) {
            int insert = userMapper1.insert(name, age);
            int i = 1 / age;// 赋值age为0故意引发事务
            return insert;
        }
     
        // 开启事务,由于使用jta+atomikos解决分布式事务,所以此处不必再指定事务
        @Transactional
        public int insertDb1AndDb2(String name, Integer age) {
            int insert = userMapper1.insert(name, age);
            int insert2 = userMapper2.insert(name, age);
            int i = 1 / age;// 赋值age为0故意引发事务
            return insert + insert2;
        }
    

    相关文章

      网友评论

        本文标题:分布式系统-分布式事务05(springboot+atomiks

        本文链接:https://www.haomeiwen.com/subject/yvftkctx.html