SpringBoot+JTA+Mybatis


版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接: https://blog.csdn.net/sinat_36596988/article/details/82149241

在實際開發中,我們一個項目可能會用到多個數據庫,通常一個數據庫對應一個數據源。這時候就要管理多數據源事務。

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

pom.xml

注意這里的druid用1.1.9


     
     
    
   
   
           
  1. <dependency>
  2. <groupId>org.springframework.boot </groupId>
  3. <artifactId>spring-boot-starter </artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot </groupId>
  7. <artifactId>spring-boot-starter-web </artifactId>
  8. </dependency>
  9. <dependency>
  10. <groupId>org.springframework.boot </groupId>
  11. <artifactId>spring-boot-starter-test </artifactId>
  12. <scope>test </scope>
  13. </dependency>
  14. <dependency>
  15. <groupId>org.mybatis.spring.boot </groupId>
  16. <artifactId>mybatis-spring-boot-starter </artifactId>
  17. <version>1.1.1 </version>
  18. </dependency>
  19. <dependency>
  20. <groupId>mysql </groupId>
  21. <artifactId>mysql-connector-java </artifactId>
  22. </dependency>
  23. <dependency>
  24. <groupId>com.alibaba </groupId>
  25. <artifactId>druid </artifactId>
  26. <version>1.1.9 </version>
  27. </dependency>
  28. <!-- JPA -->
  29. <dependency>
  30. <groupId>org.springframework.boot </groupId>
  31. <artifactId>spring-boot-starter-data-jpa </artifactId>
  32. </dependency>
  33. <dependency>
  34. <groupId>org.springframework.boot </groupId>
  35. <artifactId>spring-boot-starter-jta-atomikos </artifactId>
  36. </dependency>

配置第一個數據源


     
     
    
   
   
           
  1. import com.alibaba.druid.pool.xa.DruidXADataSource;
  2. import com.atomikos.icatch.jta.UserTransactionImp;
  3. import com.atomikos.icatch.jta.UserTransactionManager;
  4. import org.apache.ibatis.session.SqlSessionFactory;
  5. import org.mybatis.spring.SqlSessionFactoryBean;
  6. import org.mybatis.spring. annotation.MapperScan;
  7. import org.springframework.beans.factory. annotation.Qualifier;
  8. import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
  9. import org.springframework.context. annotation.Bean;
  10. import org.springframework.context. annotation.Configuration;
  11. import org.springframework.context. annotation.Primary;
  12. import org.springframework.transaction.jta.JtaTransactionManager;
  13. import javax.sql.DataSource;
  14. import javax.transaction.UserTransaction;
  15. @Configuration
  16. // // 掃描 Mapper 接口並容器管理
  17. @MapperScan(value ="mapper所在包路徑" ,sqlSessionFactoryRef = "moviesSqlSessionFactory")
  18. public class MoviesDataSourceConfig {
  19. @Bean(name = "moviesDataSource")
  20. @Primary
  21. public DataSource masterDataSource() {
  22. DruidXADataSource druidXADataSource = new DruidXADataSource();
  23. druidXADataSource.setUrl( "jdbc:mysql://localhost:3306/movies?useUnicode=true&characterEncoding=UTF8&useSSL=false");
  24. druidXADataSource.setUsername( "root");
  25. druidXADataSource.setPassword( "");
  26. AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
  27. atomikosDataSourceBean.setXaDataSource(druidXADataSource);
  28. atomikosDataSourceBean.setUniqueResourceName( "moviesDataSource");
  29. atomikosDataSourceBean.setPoolSize( 5);
  30. return atomikosDataSourceBean;
  31. }
  32. /*
  33. * 使用這個來做總事務 后面的數據源就不用設置事務了
  34. * */
  35. @Bean(name = "transactionManager")
  36. @Primary
  37. public JtaTransactionManager regTransactionManager () {
  38. UserTransactionManager userTransactionManager = new UserTransactionManager();
  39. UserTransaction userTransaction = new UserTransactionImp();
  40. return new JtaTransactionManager(userTransaction, userTransactionManager);
  41. }
  42. @Bean(name = "moviesSqlSessionFactory")
  43. @Primary
  44. public SqlSessionFactory masterSqlSessionFactory( @Qualifier("moviesDataSource") DataSource masterDataSource)
  45. throws Exception {
  46. final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
  47. sessionFactory.setDataSource(masterDataSource);
  48. return sessionFactory.getObject();
  49. }
  50. }

注意:不管有多少個數據源只要配置一個 JtaTransactionManager。

還有 DataSource里用的是DruidXADataSource ,而后注冊到AtomikosDataSourceBean並且返回。

 

配置第二個數據源


     
     
    
   
   
           
  1. import com.alibaba.druid.pool.xa.DruidXADataSource;
  2. import org.apache.ibatis.session.SqlSessionFactory;
  3. import org.mybatis.spring.SqlSessionFactoryBean;
  4. import org.mybatis.spring. annotation.MapperScan;
  5. import org.springframework.beans.factory. annotation.Qualifier;
  6. import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
  7. import org.springframework.context. annotation.Bean;
  8. import org.springframework.context. annotation.Configuration;
  9. import javax.sql.DataSource;
  10. @Configuration
  11. // // 掃描 Mapper接口
  12. @MapperScan(value ="com.sunsharing.mapper" ,sqlSessionFactoryRef = "teacherSqlSessionFactory")
  13. public class TeacherDataSourceConfig {
  14. @Bean(name = "teacherDataSource")
  15. public DataSource masterDataSource() {
  16. DruidXADataSource druidXADataSource = new DruidXADataSource();
  17. druidXADataSource.setUrl( "jdbc:mysql://localhost:3306/reactstu?useUnicode=true&characterEncoding=UTF8&useSSL=false");
  18. druidXADataSource.setUsername( "root");
  19. druidXADataSource.setPassword( "");
  20. AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
  21. atomikosDataSourceBean.setXaDataSource(druidXADataSource);
  22. atomikosDataSourceBean.setUniqueResourceName( "teacherDataSource");
  23. atomikosDataSourceBean.setPoolSize( 5);
  24. return atomikosDataSourceBean;
  25. }
  26. @Bean(name = "teacherSqlSessionFactory")
  27. public SqlSessionFactory masterSqlSessionFactory( @Qualifier("teacherDataSource") DataSource masterDataSource)
  28. throws Exception {
  29. final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
  30. sessionFactory.setDataSource(masterDataSource);
  31. return sessionFactory.getObject();
  32. }
  33. }

這里就不用配置JtaTransactionManager了。

測試:


     
     
    
   
   
           
  1. @Autowired
  2. MoviesMapper moviesMapper;
  3. @Autowired
  4. TeacherMapper teacherMapper;
  5. @RequestMapping(method = RequestMethod.GET)
  6. public MyResponseJson twodata() {
  7. for ( int i = 0;i < 5;i++) {
  8. if(i < 2) {
  9. Teacher teacher = new Teacher( "3", 10);
  10. teacherMapper.insertteacher(teacher);
  11. Movies movies = new Movies( "3", "3", 50, 10);
  12. moviesMapper.insertmovies(movies);
  13. } else {
  14. throw new RuntimeException();
  15. }
  16. }
  17. return new MyResponseJson( 200, "成功!", null);
  18. }

測試結果:可以回滾


免責聲明!

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



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