springboot整合多數據源解決分布式事務


一、前言

       springboot整合多數據源解決分布式事務。

            1.多數據源采用分包策略 

            2.全局分布式事務管理:jta-atomikos。

       在此記錄下,分享給大家。

二、springboot整合多數據源解決分布式事務

1、pom文件 依賴引入

<parent>

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


        <artifactId>spring-boot-starter-parent</artifactId>

        <version>2.1.8.RELEASE</version>

        <relativePath />

    </parent>

 

    <dependencies>

        <!-- SpringBoot 測試 -->

        <dependency>

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

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>

 

        <!-- SpringBoot web組件 -->

        <dependency>

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

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

 

        <!-- mybatis 支持 SpringBoot -->

        <dependency>

            <groupId>org.mybatis.spring.boot</groupId>

            <artifactId>mybatis-spring-boot-starter</artifactId>

            <version>1.1.1</version>

        </dependency>

 

        <!-- mysql 驅動 -->

        <dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

            <version>5.1.38</version>

        </dependency>

 

        <!-- 全局事務集中管理解決分布式事務 -->

        <dependency>

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

            <artifactId>spring-boot-starter-jta-atomikos</artifactId>

        </dependency>

 

        <!-- SpringBoot 自動配置 -->

        <dependency>

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

            <artifactId>spring-boot-configuration-processor</artifactId>

            <optional>true</optional>

        </dependency>

 

        <!-- 注解式插入/構建/優雅代碼 -->

        <dependency>

            <groupId>org.projectlombok</groupId>

            <artifactId>lombok</artifactId>

            <version>1.18.4</version>

        </dependency>

    </dependencies>

 

2 application.yml 新增配置

spring:

  datasource:

    ## 用戶數據庫

    user:

      url: jdbc:mysql://127.0.0.1:3306/yys_user

      username: root

      password: 123456

      borrowConnectionTimeout: 30

      loginTimeout: 30

      maintenanceInterval: 60

      maxIdleTime: 60

      maxLifetime: 20000

      maxPoolSize: 25

      minPoolSize: 3

      uniqueResourceName: userDataSource

      testQuery: select 1

    ## 訂單數據庫

    order:

      url: jdbc:mysql://127.0.0.1:3306/yys_order

      username: root

      password: 123456

      borrowConnectionTimeout: 30

      loginTimeout: 30

      maintenanceInterval: 60

      maxIdleTime: 60

      maxLifeTime: 20000

      maxPoolSize: 25

      minPoolSize: 3

      uniqueResourceName: orderDataSource

      testQuery: select 1

3userConfig.java

@ConfigurationProperties(prefix = "spring.datasource.user")

@Data

public class UserConfig {

    private String url;

    private String userName;

    private String password;

    private int minPoolSize;

    private int maxPoolSize;

    private int maxLifeTime;

    private int maxIdleTime;

    private int loginTimeout;

    private int maintenanceInterval;

    private int borrowConnectionTimeout;

    private String testQuery;

    private String uniqueResourceName;

}

4userDataSourceConfig.java

/**

 * 用戶數據源

 *      Config

 * @author yys

 */

@Configuration

@MapperScan(basePackages = "com.yys.user.mapper", sqlSessionTemplateRef = "userSqlSessionTemplate")

public class UserDataSourceConfig {

 

    /**

     * 創建 XADataSource

     * @return

     */

    @Bean("userDataSource")

    public DataSource userDataSource(UserConfig userConfig) throws SQLException {

        // 1、創建Mysql XADataSource

        MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();

        mysqlXaDataSource.setUrl(userConfig.getUrl());

        mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);

        mysqlXaDataSource.setPassword(userConfig.getPassword());

        mysqlXaDataSource.setUser(userConfig.getUserName());

        mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);

 

        // 2、將本地事務注冊到 Atomikos 全局事務

        AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();

        xaDataSource.setXaDataSource(mysqlXaDataSource);

        xaDataSource.setUniqueResourceName(userConfig.getUniqueResourceName());

        xaDataSource.setMinPoolSize(userConfig.getMinPoolSize());

        xaDataSource.setMaxPoolSize(userConfig.getMaxPoolSize());

        xaDataSource.setMaxLifetime(userConfig.getMaxLifeTime());

        xaDataSource.setBorrowConnectionTimeout(userConfig.getBorrowConnectionTimeout());

        xaDataSource.setLoginTimeout(userConfig.getLoginTimeout());

        xaDataSource.setMaintenanceInterval(userConfig.getMaintenanceInterval());

        xaDataSource.setMaxIdleTime(userConfig.getMaxIdleTime());

        xaDataSource.setTestQuery(userConfig.getTestQuery());

 

        return xaDataSource;

    }

 

    /**

     * 創建 SQL會話工廠

     * @param dataSource

     * @return

     * @throws Exception

     */

    @Bean("userSqlSessionFactory")

    public SqlSessionFactory userSqlSessionFactory(@Qualifier("userDataSource") DataSource dataSource) throws Exception {

        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        sqlSessionFactoryBean.setDataSource(dataSource);

        return sqlSessionFactoryBean.getObject();

    }

 

    /**

     * 創建用戶 SqlSession模板

     * @param sqlSessionFactory

     * @return

     */

    @Bean("userSqlSessionTemplate")

    public SqlSessionTemplate userSqlSessionTemplate(@Qualifier("userSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {

        return new SqlSessionTemplate(sqlSessionFactory);

    }

 

}

 

5orderConfig.java

@ConfigurationProperties(prefix = "spring.datasource.order")

@Data

public class OrderConfig {

 

    private String url;

 

    private String userName;

 

    private String password;

 

    private int minPoolSize;

 

    private int maxPoolSize;

 

    private int maxLifeTime;

 

    private int maxIdleTime;

 

    private int loginTimeout;

 

    private int maintenanceInterval;

 

    private int borrowConnectionTimeout;

 

    private String testQuery;

 

    private String uniqueResourceName;

 

}

6orderDataSourceConfig.java

/**

 * 訂單數據源

 *      Config

 * @author yys

 */

@Configuration

@MapperScan(basePackages = "com.yys.order.mapper", sqlSessionTemplateRef = "orderSqlSessionTemplate")

public class OrderDataSourceConfig {

 

    /**

     * 創建 XADataSource

     * @return

     */

    @Bean("orderDataSource")

    public DataSource orderDataSource(OrderConfig orderConfig) throws SQLException {

 

        // 1、創建Mysql XADataSource

        MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();

        mysqlXaDataSource.setUrl(orderConfig.getUrl());

        mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);

        mysqlXaDataSource.setPassword(orderConfig.getPassword());

        mysqlXaDataSource.setUser(orderConfig.getUserName());

        mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);

 

        // 2、將本地事務注冊到 Atomikos 全局事務

        AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();

        xaDataSource.setXaDataSource(mysqlXaDataSource);

        xaDataSource.setUniqueResourceName(orderConfig.getUniqueResourceName());

        xaDataSource.setMinPoolSize(orderConfig.getMinPoolSize());

        xaDataSource.setMaxPoolSize(orderConfig.getMaxPoolSize());

        xaDataSource.setMaxLifetime(orderConfig.getMaxLifeTime());

        xaDataSource.setBorrowConnectionTimeout(orderConfig.getBorrowConnectionTimeout());

        xaDataSource.setLoginTimeout(orderConfig.getLoginTimeout());

        xaDataSource.setMaintenanceInterval(orderConfig.getMaintenanceInterval());

        xaDataSource.setMaxIdleTime(orderConfig.getMaxIdleTime());

        xaDataSource.setTestQuery(orderConfig.getTestQuery());

 

        return xaDataSource;

    }

 

    /**

     * 創建 SQL會話工廠

     * @param dataSource

     * @return

     * @throws Exception

     */

    @Bean("orderSqlSessionFactory")

    public SqlSessionFactory orderSqlSessionFactory(@Qualifier("orderDataSource") DataSource dataSource) throws Exception {

        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        sqlSessionFactoryBean.setDataSource(dataSource);

        return sqlSessionFactoryBean.getObject();

    }

 

    /**

     * 創建訂單 SqlSession模板

     * @param sqlSessionFactory

     * @return

     */

    @Bean("orderSqlSessionTemplate")

    public SqlSessionTemplate orderSqlSessionTemplate(@Qualifier("orderSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {

        return new SqlSessionTemplate(sqlSessionFactory);

    }

 

}

UserService.java

public class UserService {

 

    @Autowired

    private UserMapper userMapper;

 

    @Autowired

    private OrderMapper orderMapper;

 

    // 全局事務處理器

    // 事務底層原理采用aop技術做增強

    // 無需再指定某個事務管理器,全交給 Atomikos 全局事務

    @Transactional

    public Boolean addUser(String name, Integer age, Double amount, String address) {

 

        // 操作用戶庫

        int i = userMapper.addUser(name, age);

        // 操作訂單庫

        int j = orderMapper.addOrder(amount, address);

 

        // 測試事務回滾(age = 0:回滾;age > 0:事務提交)

        int flag = 1 / age;

 

        return i > 0 && j > 0;

    }

 

 

}

springboot整合多數據源解決分布式事務


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM