JTA+SpringBoot多数据源事务一致性(三)

一、springboot整合JTA

  以两个数据库来作为例子讲解。

  1. 引入maven配置
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jta-atomikos</artifactId>
            </dependency>

     

  2. 新建jta接管driud配置文件

    @Configuration
    public class DataSourceConfig {
        
        /**
           引入配置文件数据库配置信息
        **/
        @Value("${spring.datasource.primary.url}")
        private String primaryUrl;
        
        @Value("${spring.datasource.primary.username}")
        private String primaryUsername;
        
        @Value("${spring.datasource.primary.password}")
        private String primaryPassword;
        
        @Value("${spring.datasource.primary.type}")
        private String primaryType;
        
        @Value("${spring.datasource.primary.driver-class-name}")
        private String driverClassName;
    
         //数据源1
        @Bean(initMethod = "init")
        @Primary
        @Qualifier("primaryDataSource")
        @ConfigurationProperties(prefix = "spring.datasource.primary")
        public DataSource primaryDataSource() throws SQLException {
            AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
            atomikosDataSourceBean.setUniqueResourceName("primaryDataSource");
            atomikosDataSourceBean.setXaDataSource(xaDataSource1());
            atomikosDataSourceBean.setMaxPoolSize(20);
            atomikosDataSourceBean.setMinPoolSize(3);
            atomikosDataSourceBean.setMaxLifetime(600000);
            atomikosDataSourceBean.setMaxIdleTime(600000);
            atomikosDataSourceBean.setBorrowConnectionTimeout(300000);
            atomikosDataSourceBean.setLoginTimeout(300000);
            atomikosDataSourceBean.setMaintenanceInterval(280000);
            return atomikosDataSourceBean;
        }
    
        public XADataSource xaDataSource1() throws SQLException {
            DruidXADataSource xaDataSource = new DruidXADataSource();
            xaDataSource.setUrl(primaryUrl);
            xaDataSource.setUsername(primaryUsername);
            xaDataSource.setPassword(primaryPassword);
            xaDataSource.setDriverClassName("com.mysql.jdbc.Driver");
            xaDataSource.setTestOnBorrow(true);
            xaDataSource.setTestWhileIdle(true);
            xaDataSource.setTestOnReturn(false);
            xaDataSource.setInitialSize(5);
            xaDataSource.setMinIdle(5);
            xaDataSource.setMaxActive(20);
            xaDataSource.setMaxWait(600000);
            xaDataSource.setTimeBetweenEvictionRunsMillis(600000);
            xaDataSource.setMinEvictableIdleTimeMillis(3000000);
            xaDataSource.setValidationQuery("SELECT 1 FROM DUAL");
            xaDataSource.setPoolPreparedStatements(true);
            xaDataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
            xaDataSource.setFilters("stat,wall,log4j");
            xaDataSource.setConnectionProperties("druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500");
            xaDataSource.setUseGlobalDataSourceStat(true);
            xaDataSource.setRemoveAbandonedTimeout(1800);//30分钟
            return xaDataSource;
        }
    
        @Bean(name = "primaryJdbcTemplate")
        @Primary
        public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {
            return new JdbcTemplate(dataSource);
        }
    
        //数据源2的配置信息和数据源1相同,这里不再写入。
    
        ----------------------------------------------------
    
       /**
         * 注入事物管理器
         * @return
         */
        @Bean(name = "jtm")
        public JtaTransactionManager regTransactionManager () {
            UserTransactionManager userTransactionManager = new UserTransactionManager();
            UserTransaction userTransaction = new UserTransactionImp();
            return new JtaTransactionManager(userTransaction, userTransactionManager);
        }
         
    
    }

     

  3. 业务中引入JTA事务

    //引入spring事务注解,事务名字要和配置文件的事务管理器名字一样,这样就纳入JTA管理,JTA会生成一个序列号
    @Transactional(transactionManager = "jtm", rollbackFor = MyException.class)
    public RestResponse doCreateFacheTbl(Map<String, Object> params) throws MyException {
        List<TtVehicle> ttvehiclelist = this.iTtVehicleService.findTtVehicleByVin(StringUtil.toString(params.get("vin")),
                        brandId);//从数据源1取值
         Map<String, Object> ttvehicleMap = new HashMap<String, Object>();
         ttvehicleMap.put("vin", params.get("vin"));
         ttvehicleMap.put("brand_id", brandId);// 品牌
         ttvehicleMap.put("engine_no", ifaproductMap.get("engno"));// 发动机号
         ttvehicleMap.put("vehicel_flag", "K");// 车辆状态
         this.iTtVehicleService.doCreateTtVehicle(ttvehicleMap, user); //新增数据源1数据
         
         this.iTiVehicleInoutService.doCreateTiVehicleInout(ttvehicleMap, user);//新增数据源2日志表
    }

    总结: 

             通过以上可以看出springboot引入JTA只需接管相应的数据源信息,然后配置对应的事务管理器,直接在业务代码中引入即可。

Spring Boot中,我们可以使用`@Transactional`注解来实现事务管理。在多数据源的情况下,我们需要使用JTAJava Transaction API)来实现分布式事务一致性JTA提供了一个全局事务管理器来管理多个数据源的事务,在Spring Boot中,我们可以使用类似Atomikos、Bitronix和Narayana等JTA事务管理器。 具体来说,我们需要在Spring Boot中配置JTA事务管理器,并在代码中使用`@Transactional`注解来声明事务。同时,我们还需要使用`@Transactional(value = "transactionManager")`注解来指定特定数据源的事务管理器。 具体的实现过程可以参考以下步骤: 1. 在Spring Boot中添加JTA事务管理器的依赖,例如Atomikos: ```xml <dependency> <groupId>com.atomikos</groupId> <artifactId>atomikos-core</artifactId> <version>4.0.6</version> </dependency> <dependency> <groupId>com.atomikos</groupId> <artifactId>atomikos-essentials</artifactId> <version>4.0.6</version> </dependency> ``` 2. 配置数据源和JTA事务管理器: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/db1 spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource2.url=jdbc:mysql://localhost:3306/db2 spring.datasource2.username=root spring.datasource2.password=root spring.datasource2.driver-class-name=com.mysql.jdbc.Driver spring.jta.atomikos.connectionfactory.borrow-connection-timeout=30 spring.jta.atomikos.connectionfactory.min-pool-size=5 spring.jta.atomikos.connectionfactory.max-pool-size=20 spring.jta.atomikos.connectionfactory.test-query=SELECT 1 spring.jta.atomikos.datasource.ds1.xa-data-source-class-name=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource spring.jta.atomikos.datasource.ds1.unique-resource-name=ds1 spring.jta.atomikos.datasource.ds1.user=root spring.jta.atomikos.datasource.ds1.password=root spring.jta.atomikos.datasource.ds1.xa-properties.url=jdbc:mysql://localhost:3306/db1 spring.jta.atomikos.datasource.ds2.xa-data-source-class-name=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource spring.jta.atomikos.datasource.ds2.unique-resource-name=ds2 spring.jta.atomikos.datasource.ds2.user=root spring.jta.atomikos.datasource.ds2.password=root spring.jta.atomikos.datasource.ds2.xa-properties.url=jdbc:mysql://localhost:3306/db2 ``` 3. 在代码中使用`@Transactional`注解来声明事务,并使用`@Transactional(value = "transactionManager")`注解来指定特定数据源的事务管理器: ```java @Service public class MyService { @Autowired private MyRepository myRepository; @Transactional(value = "transactionManager") public void doSomething() { // 在这里使用myRepository进行数据库操作 } @Transactional(value = "transactionManager2") public void doSomethingElse() { // 在这里使用myRepository进行数据库操作 } } ``` 通过以上步骤,我们可以在Spring Boot中实现多数据源事务管理,并且保证分布式事务一致性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值