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

  • 相关阅读:
    线性表之顺序表的结构与实现
    (转)面试题1:第一个只出现一次的字符
    c++ 虚基类应用
    c++ 多重继承
    c++ 单继承派生类的构造函数
    c++ 构造函数
    深入 Struts2 的配置
    c++ 结构体
    深入浅出C指针
    HTML5 小实例
  • 原文地址:https://www.cnblogs.com/qq1141100952com/p/11548257.html
Copyright © 2011-2022 走看看