zoukankan      html  css  js  c++  java
  • (附源码gitHub下载地址)spring boot -jta-atomikos分布式事务

           应用场景:双数据源,就是某些项目会涉及到两个数据源或者两个以上的数据源,这个多数据源的项目一般是数据同步,也就是把数据从另一个系统中,保存到另一个系统,两边的 数据库又不一样,比如一个Mysql、一个Sql Server。但是不管是什么类型的数据库,我们都不管,直接连接就是。

          为什么要使用分布式事务:顾名思义,事务就是回滚,比如如果一个在保存数据的时候,在A数据库已经 保存,但是在保存数据在B的过程抛出异常,那么是不是应该全部回滚,把已经 保存了的A、B数据库的数据全部回滚?答案是确定的。下面就解说:

               pom.xml主要依赖:

           <dependency>
                <groupId>tk.mybatis</groupId>
                <artifactId>mapper-spring-boot-starter</artifactId>
                <version>2.0.0</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jta-atomikos</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.10</version>
            </dependency>
    

      

              properties配置文件:

             #数据源一
    spring.datasource.primary.url=jdbc:mysql://localhost:3306/test spring.datasource.primary.username=root spring.datasource.primary.password=root spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver spring.datasource.primary.xa-data-source-class-name=com.alibaba.druid.pool.xa.DruidXADataSource
    #数据源二 spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test1 spring.datasource.secondary.username=root spring.datasource.secondary.password=root spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver spring.datasource.secondary.xa-data-source-class-name=com.alibaba.druid.pool.xa.DruidXADataSource

     

             数据源的配置类:DataSourceConfig.class

            

    import com.alibaba.druid.pool.xa.DruidXADataSource;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    
    
    @Configuration
    public class DataSourceConfig {
        //这里一定要加主数据源的注解
        @Primary
        @Bean(name = "primaryProperty")
        @ConfigurationProperties(prefix = "spring.datasource.primary")
        public DruidXADataSource primaryDataSource() {
            return new DruidXADataSource();
        }
        
    //这里是第二个数据源 @Bean(name = "secondaryProperty") @ConfigurationProperties(prefix = "spring.datasource.secondary") public DruidXADataSource secondaryDataSource() { return new DruidXADataSource(); } }

      

         再分别配置他们的数据源:以便包扫描、事务交给jta-atomikos统一管理   

        主数据源配置类:

    import com.alibaba.druid.pool.xa.DruidXADataSource;
    import com.atomikos.jdbc.AtomikosDataSourceBean;
    
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.SqlSessionTemplate;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    
    import javax.sql.DataSource;
    
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import tk.mybatis.spring.annotation.MapperScan;
    
    @Configuration
    @MapperScan(basePackages = {"com.example.dao.primary"}, sqlSessionTemplateRef = "primarySqlSessionTemplate")
    public class PrimaryDBConfig {
    
        @Bean(name = "primaryDataSource")
        public DataSource dataSourceCar(@Qualifier("primaryProperty") DruidXADataSource druidXADataSource) {
            AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
            xaDataSource.setXaDataSource(druidXADataSource);
            xaDataSource.setUniqueResourceName("primaryDataSource");
            return xaDataSource;
        }
    
        @Bean(name = "primarySqlSessionFactory")
        public SqlSessionFactory sqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource)
                throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/primary/*Mapper.xml"));//扫描指定目录的xml
            return bean.getObject();
        }
    
        @Bean(name = "primarySqlSessionTemplate")
        public SqlSessionTemplate sqlSessionTemplate(
                @Qualifier("primarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    }
    

      

           同理,第二个数据源的配置SecondaryDBConfig.java

    @Configuration
    @MapperScan(basePackages = {"com.example.dao.secondary"}, sqlSessionTemplateRef = "secondarySqlSessionTemplate")
    public class SecondaryDBConfig {
    
        @Bean(name = "secondaryDataSource")
        public DataSource dataSourceCar(@Qualifier("secondaryProperty") DruidXADataSource druidXADataSource) {
            AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
            xaDataSource.setXaDataSource(druidXADataSource);
            xaDataSource.setUniqueResourceName("secondaryDataSource");
            return xaDataSource;
        }
    
        @Bean(name = "secondarySqlSessionFactory")
        public SqlSessionFactory sqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource)
                throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/secondary/*Mapper.xml"));//扫描指定目录的xml
            return bean.getObject();
        }
    
        @Bean(name = "secondarySqlSessionTemplate")
        public SqlSessionTemplate sqlSessionTemplate(
                @Qualifier("secondarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    }
    

      

    最后我们还需要配置事务管理的配置类:TransactionManagerConfig.java,以便把数据源一,数据源二全部交给jta-atomikos管理,实现分布式事务管理:

    import com.atomikos.icatch.jta.UserTransactionImp;
    import com.atomikos.icatch.jta.UserTransactionManager;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.DependsOn;
    import org.springframework.transaction.PlatformTransactionManager;
    import org.springframework.transaction.jta.JtaTransactionManager;
    
    import javax.transaction.TransactionManager;
    import javax.transaction.UserTransaction;
    
    @Configuration
    public class TransactionManagerConfig {
    
        @Bean(name = "userTransaction")
        public UserTransaction userTransaction() throws Throwable {
            UserTransactionImp userTransactionImp = new UserTransactionImp();
            userTransactionImp.setTransactionTimeout(10000);
            return userTransactionImp;
        }
    
        @Bean(name = "atomikosTransactionManager")
        public TransactionManager atomikosTransactionManager() throws Throwable {
            UserTransactionManager userTransactionManager = new UserTransactionManager();
            userTransactionManager.setForceShutdown(false);
            return userTransactionManager;
        }
    
        @Bean(name = "transactionManager")
        @DependsOn({ "userTransaction", "atomikosTransactionManager" })
        public PlatformTransactionManager transactionManager() throws Throwable {
            return new JtaTransactionManager(userTransaction(),atomikosTransactionManager());
        }
    }
    

      最后我们在service类上加上注解:@Transactional(value = "transactionManager", rollbackFor = Exception.class)

    当value = "transactionManager",则是分布式事务的管理。至此,全部完成。

    gitHub完整项目下载地址:https://gitee.com/qhThomas/springboot-mybatis-duria.git

  • 相关阅读:
    Candy leetcode java
    Trapping Rain Water leetcode java
    Best Time to Buy and Sell Stock III leetcode java
    Best Time to Buy and Sell Stock II leetcode java
    Best Time to Buy and Sell Stock leetcode java
    Maximum Subarray leetcode java
    Word Break II leetcode java
    Word Break leetcode java
    Anagrams leetcode java
    Clone Graph leetcode java(DFS and BFS 基础)
  • 原文地址:https://www.cnblogs.com/qq1141100952com/p/11548257.html
Copyright © 2011-2022 走看看