springboot多数据源事务实现

1.添加依赖

    org.springframework.boot
    spring-boot-starter-jta-atomikos

2.在配置文件添加多数据源配置,与log4jdbc不能共用!

#数据源1
master.datasource.url=jdbc:mysql://127.0.0.1:3306/xxx?useSSL=false&useUnicode=true&characterEncoding=UTF-8
master.datasource.username=root
master.datasource.password=root
master.datasource.driverClassName=com.mysql.jdbc.Driver
master.datasource.minPoolSize = 3
master.datasource.maxPoolSize = 25
master.datasource.maxLifetime = 20000
master.datasource.borrowConnectionTimeout = 30
master.datasource.loginTimeout = 30
master.datasource.maintenanceInterval = 60
master.datasource.maxIdleTime = 60
master.datasource.testQuery = select 1
#数据源2
test.datasource.url=jdbc:mysql://127.0.0.1:3306/xxx?useSSL=false&useUnicode=true&characterEncoding=UTF-8
test.datasource.username=root
test.datasource.password=root
test.datasource.driverClassName=com.mysql.jdbc.Driver
test.datasource.minPoolSize = 3
test.datasource.maxPoolSize = 25
test.datasource.maxLifetime = 20000
test.datasource.borrowConnectionTimeout = 30
test.datasource.loginTimeout = 30
test.datasource.maintenanceInterval = 60
test.datasource.maxIdleTime = 60
test.datasource.testQuery = select 1

数据源n
....

3.增加配置类,多数据源多个配置类

import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;

@Configuration
//扫描 Mapper 接口并容器管理
@MapperScan(basePackages = "xx.mapper.master<改>", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig<改> {


    @Value("${master.datasource.url<改>}")
    private String url;

    @Value("${master.datasource.username}")
    private String user;

    @Value("${master.datasource.password}")
    private String password;

    @Value("${master.datasource.driverClassName}")
    private String driverClass;
    
    @Value("${master.datasource.minPoolSize}")
    private int minPoolSize;

    @Value("${master.datasource.maxPoolSize}")
    private int maxPoolSize;
    
    @Value("${master.datasource.maxLifetime}")
    private int maxLifetime;
    
    @Value("${master.datasource.borrowConnectionTimeout}")
    private int borrowConnectionTimeout;
    
    @Value("${master.datasource.loginTimeout}")
    private int loginTimeout;
    
    @Value("${master.datasource.maintenanceInterval}")
    private int maintenanceInterval;
    
    @Value("${master.datasource.maxIdleTime}")
    private int maxIdleTime;
    
    @Value("${master.datasource.testQuery}")
    private String testQuery;

    @Bean(name = "masterDataSource")
    public DataSource clusterDataSource() throws SQLException {
        MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
        mysqlXaDataSource.setUrl(url);
        mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
        mysqlXaDataSource.setPassword(password);
        mysqlXaDataSource.setUser(user);
        mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
        // 创建Atomikos全局事务,所有的事务注册进来
        AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
        xaDataSource.setXaDataSource(mysqlXaDataSource);
        xaDataSource.setUniqueResourceName("masterDataSource<改>"); // masterDataSource这个数据源的注册
        xaDataSource.setMinPoolSize(minPoolSize);
        xaDataSource.setMaxPoolSize(maxPoolSize);
        xaDataSource.setMaxLifetime(maxLifetime);
        xaDataSource.setBorrowConnectionTimeout(borrowConnectionTimeout);
        xaDataSource.setLoginTimeout(loginTimeout);
        xaDataSource.setMaintenanceInterval(maintenanceInterval);
        xaDataSource.setMaxIdleTime(maxIdleTime);
        xaDataSource.setTestQuery(testQuery);
        return xaDataSource;
    }

    @Bean(name = "masterSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
    }

    
    @Bean(name = "masterSqlSessionTemplate")
    public SqlSessionTemplate masterSqlSessionTemplate(
            @Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

4.根据不同数据源添加不同包,做不同的实现
xx.mapper.master
xx.mapper.test

xx.service.master
xx.service.test

xx.service.impl.master
xx.service.impl.test

5.服务实现层,注入不同数据源的mapper达到在同一函数操作不同数据源的目的
@Autowired
MasterMapper masterMapper;

@Autowired
TestMapper testMapper;

@Transactional
public void test(){
    masterMapper.add();
    testMapper.add();
}

在test函数中,只要有异常抛出,所有数据源的更新操作都会回滚.

你可能感兴趣的:(随手笔)