使用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,想想同时操作多个数据库,是不是很爽啊,哈哈哈。

原文地址:https://www.cnblogs.com/wang66a/p/12069286.html

时间: 2024-10-28 10:26:19

使用springboot+jta+atomikos 分布式事物管理的相关文章

Springboot入门之分布式事务管理

springboot默认集成事务,只主要在方法上加上@Transactional即可. 分布式事务一种情况是针对多数据源,解决方案这里使用springboot+jta+atomikos来解决 一.pom文件 <groupId>cn.iponkan</groupId>    <artifactId>springboot-jsp</artifactId>    <version>1.0-SNAPSHOT</version>     <

Atomikos实现分布式事物管理

分布式事务管理,简单来说就是多个数据库之间的事务管理.之前也试过使用Spring动态切换数据库,通过继承AbstractRoutingDataSource重写determineCurrentLookupKey()方法,来决定使用那个数据库.在开启事务之前,通过改变lookupKey来达到切换数据源目的.但是这种方法多个数据库之前没办法做事务管理,或许对于主从(读写)数据库会好用一些,而对于需要一个操作中更新多个数据库的情况,使用Atomikos或许会更好一些. 本文采用spring4+hiber

springboot数据库操作及事物管理操作例子

一.配置文件 application.yml 1 spring: 2 profiles: 3 active: dev 4 datasource: 5 driver-class-name: com.mysql.jdbc.Driver 6 url: jdbc:mysql://127.0.0.1:3306/dbgirl 7 username: root 8 password: 123456 9 jpa: 10 hibernate: 11 ddl-auto: update 12 show-sql: tr

第十一章 SpringBoot事物管理器

一.springboot整合事物管理 springboot默认集成事物,只主要在方法上加上@Transactional即可 二.SpringBoot分布式事物管理 使用springboot+jta+atomikos 分布式事物管理 1.pom文件 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-parent</artifactId> <

springboot(九):事物管理

SpringBoot整合事物管理 Springboot默认集成事物,只主要在方法上加上@Transactional即可. 多数据源情况下事物怎么管理事物 对于这种传统的分布式事物管理,采用jta+atomikos 分布式事物管理.Atomikos 是一个为Java平台提供增值服务的并且开源类事务管理器. 新增jta-atomikos依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifa

spring+springMVC+Mybatis架构下采用AbstractRoutingDataSource、atomikos、JTA实现多数据源灵活切换以及分布式事务管理

背景: 1.系统采用SSM架构.需要在10多个MYSQL数据库之间进行切换并对数据进行操作,上篇博文<springMVC+Mybatis(使用AbstractRoutingDataSource实现多数据源切换时)事务管理未生效的解决办法> 2.第一步先通过AbstractRoutingDataSource实现了多数据源的灵活切换,但是后来发现事务不起作用: 3.发现问题是因为重复扫描service包导致第二次扫入容器的BEAN没有纳入事务管理,因此在springMVC的配置文件中排除了对Ser

spring 事物管理

1 在spring中支持编程式事物和声明式事务管理,通常使用声明式事物管理,声明式的事物管理是基于aop机制实现的使用很方便. 2 spring支持单一数据库资源的事物管理和跨越多个数据库资源的事物管理既JTA全局事物. 3 在spring中提供了多个事物管理类,常用的是;DataSourceTransactionManager,HibernateTransactionManager和JtaTransactionManager. DataSourceTransactionManager :数据源

Spring多数据源分布式事务管理/springmvc+spring+atomikos[jta]+druid+mybatis

项目进行读写分离及分库分表,在一个业务中,在一个事务中处理时候将切换多个数据源,需要保证同一事务多个数据源数据的一致性.此处使用atomikos来实现:最后附源码: 1:spring3.0之后不再支持jtom[jta]了,第三方开源软件atomikos(http://www.atomikos.com/)来实现. 2:org.springframework.transaction.jta.JotmFactoryBean类,spring-tx-2.5.6.jar中有此类,spring-tx-3.0.

Spring事务隔离级别与传播机制,spring+mybatis+atomikos实现分布式事务管理

本文转载于本人另一博客[http://blog.csdn.net/liaohaojian/article/details/68488150] 1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). 原子性(Atomicity):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做: 一致性(Consistency):在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是应该处于正确