zoukankan      html  css  js  c++  java
  • 使用springboot+jta+atomikos 分布式事物管理

    当项目在连接多个数据库时可能会发生事务问题,即一个库的事务不可能去操作另一个数据库的事务,这时就需要使用atomikos对数据库的事务进行统一的管理

    第一步添加atomikos的依赖

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-jta-atomikos</artifactId>
    </dependency>
    

    第二步配置数据源,我这里有2个数据库(ruan和youxianqi),你有多少就加多少。

    spring:
      datasource:
        system:
          jdbc-url: jdbc:oracle:thin:@localhost:1521/orcl
          driver-class-name: oracle.jdbc.OracleDriver
          username: yuan
          password: 1234
          initial-size: 5
          min-idle: 5
          max-active: 20
          min-evictable-idle-time-millis: 300000
          validation-query: SELECT 1 FROM DUAL
          test-while-idle: true
        kllogt:
          jdbc-url: jdbc:oracle:thin:@localhost:1521/orcl
          driver-class-name: oracle.jdbc.OracleDriver
          username: youxianqi
          password: youxianqi
          initial-size: 5
          min-idle: 5
          max-active: 20
          min-evictable-idle-time-millis: 300000
          validation-query: SELECT 1 FROM DUAL
          test-while-idle: true
    logging:
      level:
        org.springframework.web: debug
    
    


    然后创建DBConfig1和DBConfig2,这两个实体类就是存放两个数据源的数据的。

    package com.cgb.config;
     
     
    import org.springframework.boot.context.properties.ConfigurationProperties;
     
    @ConfigurationProperties(prefix = "spring.datasource.system")
    public class DBConfig1 {
     
        private String jdbc-url;
        private String username;
        private String password;
     
        private int minPoolSize;
     
        private int maxPoolSize;
     
        private int maxLifetime;
     
        private int borrowConnectionTimeout;
     
        private int loginTimeout;
     
        private int maintenanceInterval;
     
        private int maxIdleTime;
     
        private String testQuery;
     
        public String getJdbc-url() {
            return url;
        }
     
        public void setJdbc-url(String jdbc-url) {
            this.jdbc-url= jdbc-url;
        }
     
        public String getUsername() {
            return username;
        }
     
        public void setUsername(String username) {
            this.username = username;
        }
     
        public String getPassword() {
            return password;
        }
     
        public void setPassword(String password) {
            this.password = password;
        }
     
        public int getMinPoolSize() {
            return minPoolSize;
        }
     
        public void setMinPoolSize(int minPoolSize) {
            this.minPoolSize = minPoolSize;
        }
     
        public int getMaxPoolSize() {
            return maxPoolSize;
        }
     
        public void setMaxPoolSize(int maxPoolSize) {
            this.maxPoolSize = maxPoolSize;
        }
     
        public int getMaxLifetime() {
            return maxLifetime;
        }
     
        public void setMaxLifetime(int maxLifetime) {
            this.maxLifetime = maxLifetime;
        }
     
        public int getBorrowConnectionTimeout() {
            return borrowConnectionTimeout;
        }
     
        public void setBorrowConnectionTimeout(int borrowConnectionTimeout) {
            this.borrowConnectionTimeout = borrowConnectionTimeout;
        }
     
        public int getLoginTimeout() {
            return loginTimeout;
        }
     
        public void setLoginTimeout(int loginTimeout) {
            this.loginTimeout = loginTimeout;
        }
     
        public int getMaintenanceInterval() {
            return maintenanceInterval;
        }
     
        public void setMaintenanceInterval(int maintenanceInterval) {
            this.maintenanceInterval = maintenanceInterval;
        }
     
        public int getMaxIdleTime() {
            return maxIdleTime;
        }
     
        public void setMaxIdleTime(int maxIdleTime) {
            this.maxIdleTime = maxIdleTime;
        }
     
        public String getTestQuery() {
            return testQuery;
        }
     
        public void setTestQuery(String testQuery) {
            this.testQuery = testQuery;
        }
     
    }


    然后创建两个数据源RuanMyBatisConfig和YouMyBatisConfig,注意@Primary注解只能有一个。

    package com.cgb.datasource;
     
    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.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import com.atomikos.jdbc.AtomikosDataSourceBean;
    import com.cgb.config.DBConfig1;
    import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
     
    @Configuration
    @MapperScan(basePackages = "com.cgb.ruan", sqlSessionTemplateRef = "testSqlSessionTemplate")
    public class RuanMyBatisConfig {
     
        // 配置数据源
        @Primary
        @Bean(name = "dataSource1")
        public DataSource testDataSource(DBConfig1 testConfig) throws SQLException {
            MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
            mysqlXaDataSource.setUrl(testConfig.getUrl());
            mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
            mysqlXaDataSource.setPassword(testConfig.getPassword());
            mysqlXaDataSource.setUser(testConfig.getUsername());
            mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
     
            AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
            xaDataSource.setXaDataSource(mysqlXaDataSource);
            xaDataSource.setUniqueResourceName("dataSource1");
     
            xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
            xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
            xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
            xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
            xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
            xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
            xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
            xaDataSource.setTestQuery(testConfig.getTestQuery());
            return xaDataSource;
        }
     
        @Bean(name = "testSqlSessionFactory")
        public SqlSessionFactory testSqlSessionFactory(@Qualifier("dataSource1") DataSource dataSource)
                throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            return bean.getObject();
        }
     
        @Bean(name = "testSqlSessionTemplate")
        public SqlSessionTemplate testSqlSessionTemplate(
                @Qualifier("testSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    }


    其实在多个数据源的时候,我们怎么去指定数据库呢?

    其中一个做法是写注解,表明使用哪个数据库,但是这种是不是很麻烦。最好的做法是分包管理:

    好啦,大功告成,我们来看看效果吧。

    我们发现控制台打印添加学生成功,好我们看看数据库里有没有数据呢?

    毫无疑问是没有的,说明事务起作用了。那我们把那行异常代码注释掉,再看看效果。成功了,去看看数据库有没有呢。

    ojbk,想想同时操作多个数据库,是不是很爽啊,哈哈哈。
     

    小蘑菇
  • 相关阅读:
    Java-16 常用包装类
    Java-15 String类
    flask实现web端微信登录
    Flask-excel导出数据
    Java-14 单例模式
    Java-13 接口
    Java-12 抽象类
    结对项目:一个自动生成小学四则运算题目的命令行程序(c++)
    软工作业:第一次个人项目作业
    操作系统笔记一:操作系统引论
  • 原文地址:https://www.cnblogs.com/wang66a/p/12069286.html
Copyright © 2011-2022 走看看