springboot---使用jta+atomikos管理多数据源事务

在实际开发中,我们一个项目可能会用到多个数据库,通常一个数据库对应一个数据源。这时候就要管理多数据源事务。

什么是jta:https://www.ibm.com/developerworks/cn/java/j-lo-jta/

pom.xml

注意这里的druid用1.1.9

	
			org.springframework.boot
			spring-boot-starter
		
		
			org.springframework.boot
			spring-boot-starter-web
		
		
			org.springframework.boot
			spring-boot-starter-test
			test
		
		
			org.mybatis.spring.boot
			mybatis-spring-boot-starter
			1.1.1
		
		
			mysql
			mysql-connector-java
		
		
			com.alibaba
			druid
			1.1.9
		
		
		
			org.springframework.boot
			spring-boot-starter-data-jpa
		
		
			org.springframework.boot
			spring-boot-starter-jta-atomikos
		

配置第一个数据源

import com.alibaba.druid.pool.xa.DruidXADataSource;
import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.jta.JtaTransactionManager;
import javax.sql.DataSource;
import javax.transaction.UserTransaction;


@Configuration
// // 扫描 Mapper 接口并容器管理
@MapperScan(value ="mapper所在包路径" ,sqlSessionFactoryRef = "moviesSqlSessionFactory")
public class MoviesDataSourceConfig {


    @Bean(name = "moviesDataSource")
    @Primary
    public DataSource masterDataSource() {
        DruidXADataSource druidXADataSource = new DruidXADataSource();
        druidXADataSource.setUrl("jdbc:mysql://localhost:3306/movies?useUnicode=true&characterEncoding=UTF8&useSSL=false");
        druidXADataSource.setUsername("root");
        druidXADataSource.setPassword("");

        AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
        atomikosDataSourceBean.setXaDataSource(druidXADataSource);
        atomikosDataSourceBean.setUniqueResourceName("moviesDataSource");
        atomikosDataSourceBean.setPoolSize(5);

        return atomikosDataSourceBean;
    }

    /*
    * 使用这个来做总事务 后面的数据源就不用设置事务了
    * */
    @Bean(name = "transactionManager")
    @Primary
    public JtaTransactionManager regTransactionManager () {
        UserTransactionManager userTransactionManager = new UserTransactionManager();
        UserTransaction userTransaction = new UserTransactionImp();
        return new JtaTransactionManager(userTransaction, userTransactionManager);
    }

    @Bean(name = "moviesSqlSessionFactory")
    @Primary
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("moviesDataSource") DataSource masterDataSource)
        throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(masterDataSource);
        return sessionFactory.getObject();
    }



}

注意:不管有多少个数据源只要配置一个 JtaTransactionManager。

还有 DataSource里用的是DruidXADataSource ,而后注册到AtomikosDataSourceBean并且返回。

 

配置第二个数据源

import com.alibaba.druid.pool.xa.DruidXADataSource;

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

import javax.sql.DataSource;

@Configuration
// // 扫描 Mapper接口
@MapperScan(value ="com.sunsharing.mapper" ,sqlSessionFactoryRef = "teacherSqlSessionFactory")
public class TeacherDataSourceConfig {


    @Bean(name = "teacherDataSource")
    public DataSource masterDataSource() {
        DruidXADataSource druidXADataSource = new DruidXADataSource();
        druidXADataSource.setUrl("jdbc:mysql://localhost:3306/reactstu?useUnicode=true&characterEncoding=UTF8&useSSL=false");
        druidXADataSource.setUsername("root");
        druidXADataSource.setPassword("");

        AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
        atomikosDataSourceBean.setXaDataSource(druidXADataSource);
        atomikosDataSourceBean.setUniqueResourceName("teacherDataSource");
        atomikosDataSourceBean.setPoolSize(5);
        return atomikosDataSourceBean;
    }


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

}

这里就不用配置JtaTransactionManager了。

测试:

 @Autowired
    MoviesMapper moviesMapper;

    @Autowired
    TeacherMapper teacherMapper;


    @RequestMapping(method = RequestMethod.GET)
    public MyResponseJson twodata() {
        for (int i = 0;i < 5;i++) {
            if(i < 2) {
                Teacher teacher = new Teacher("3", 10);
                teacherMapper.insertteacher(teacher);
                Movies movies = new Movies("3", "3", 50, 10);
                moviesMapper.insertmovies(movies);
   
            }else {
                throw new RuntimeException();
            }
        }
        return new MyResponseJson(200, "成功!", null);
    }

测试结果:可以回滚

你可能感兴趣的:(springboot---使用jta+atomikos管理多数据源事务)