(附源碼gitHub下載地址)spring boot -jta-atomikos分佈式事務

       應用場景:雙數據源,就是某些項目會涉及到兩個數據源或者兩個以上的數據源,這個多數據源的項目通常是數據同步,也就是把數據從另外一個系統中,保存到另外一個系統,兩邊的 數據庫又不同,好比一個Mysql、一個Sql Server。可是無論是什麼類型的數據庫,咱們都無論,直接鏈接就是。html

      爲何要使用分佈式事務:顧名思義,事務就是回滾,好比若是一個在保存數據的時候,在A數據庫已經 保存,可是在保存數據在B的過程拋出異常,那麼是否是應該所有回滾,把已經 保存了的A、B數據庫的數據所有回滾?答案是肯定的。下面就解說:java

 

           pom.xml主要依賴:mysql

 

<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配置文件:git

 

#數據源一
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.classspring

        

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統一管理   sql

    主數據源配置類:數據庫

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.javaapache

@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管理,實現分佈式事務管理:springboot

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)session

當value = "transactionManager",則是分佈式事務的管理。至此,所有完成。

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

 

原文出處:https://www.cnblogs.com/qq1141100952com/p/11548257.html

相關文章
相關標籤/搜索