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整合多数据源解决分布式事务

原文地址:https://www.cnblogs.com/bruce1992/p/13779568.html