springboot jta atomikos实现分布式事物管理

这篇文章主要介绍了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,想想同时操作多个数据库,是不是很爽啊,哈哈哈。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Spring Boot微服务如何集成fescar解决分布式事务问题

    什么是fescar? 关于fescar的详细介绍,请参阅fescar wiki. 传统的2PC提交协议,会持有一个全局性的锁,所有局部事务预提交成功后一起提交,或有一个局部事务预提交失败后一起回滚,最后释放全局锁.锁持有的时间较长,会对并发造成较大的影响,死锁的风险也较高. fescar的创新之处在于,每个局部事务执行完立即提交,释放本地锁:它会去解析你代码中的sql,从数据库中获得事务提交前的事务资源即数据,存放到undo_log中,全局事务协调器在回滚的时候直接使用undo_log中的数据覆

  • spring boot整合redis实现shiro的分布式session共享的方法

    我们知道,shiro是通过SessionManager来管理Session的,而对于Session的操作则是通过SessionDao来实现的,默认的情况下,shiro实现了两种SessionDao,分别为CachingSessionDAO和MemorySessionDAO,当我们使用EhCache缓存时,则是使用的CachingSessionDAO,不适用缓存的情况下,就会选择基于内存的SessionDao.所以,如果我们想实现基于Redis的分布式Session共享,重点在于重写Session

  • SpringBoot集成Redisson实现分布式锁的方法示例

    上篇 <SpringBoot 集成 redis 分布式锁优化>对死锁的问题进行了优化,今天介绍的是 redis 官方推荐使用的 Redisson ,Redisson 架设在 redis 基础上的 Java 驻内存数据网格(In-Memory Data Grid),基于NIO的 Netty 框架上,利用了 redis 键值数据库.功能非常强大,解决了很多分布式架构中的问题. Github的wiki地址: https://github.com/redisson/redisson/wiki 官方文档

  • SpringBoot+Dubbo+Seata分布式事务实战详解

    前言 Seata 是 阿里巴巴开源的分布式事务中间件,以高效并且对业务0侵入的方式,解决微服务场景下面临的分布式事务问题. 事实上,官方在GitHub已经给出了多种环境下的Seata应用示例项目,地址:https://github.com/seata/seata-samples. 为什么笔者要重新写一遍呢,主要原因有两点: 官网代码示例中,依赖太多,分不清哪些有什么作用 Seata相关资料较少,笔者在搭建的过程中,遇到了一些坑,记录一下 一.环境准备 本文涉及软件环境如下: SpringBoot

  • Spring中使用atomikos+druid实现经典分布式事务的方法

    经典分布式事务,是相对互联网中的柔性分布式事务而言,其特性为ACID原则,包括原子性(Atomictiy).一致性(Consistency).隔离性(Isolation).持久性(Durabilit): 原子性:事务是一个包含一系列操作的原子操作.事务的原子性确保这些操作全部完成或者全部失败. 一致性:一旦事务的所有操作结束,事务就被提交.然后你的数据和资源将处于遵循业务规则的一直状态. 隔离性:因为同时在相同数据集上可能有许多事务处理,每个事务应该与其他事务隔离,避免数据破坏. 持久性:一旦事

  • 详解Springboot分布式限流实践

    高并发访问时,缓存.限流.降级往往是系统的利剑,在互联网蓬勃发展的时期,经常会面临因用户暴涨导致的请求不可用的情况,甚至引发连锁反映导致整个系统崩溃.这个时候常见的解决方案之一就是限流了,当请求达到一定的并发数或速率,就进行等待.排队.降级.拒绝服务等... 限流算法介绍 a.令牌桶算法 令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务. 当桶满时,新添加的令牌被丢弃或拒绝. b.漏桶算法 其主要目的是控制

  • 浅谈Java(SpringBoot)基于zookeeper的分布式锁实现

    通过zookeeper实现分布式锁 1.创建zookeeper的client 首先通过CuratorFrameworkFactory创建一个连接zookeeper的连接CuratorFramework client public class CuratorFactoryBean implements FactoryBean<CuratorFramework>, InitializingBean, DisposableBean { private static final Logger LOGG

  • spring整合atomikos实现分布式事务的方法示例

    前言 Atomikos 是一个为Java平台提供增值服务的并且开源类事务管理器,主要用于处理跨数据库事务,比如某个指令在A库和B库都有写操作,业务上要求A库和B库的写操作要具有原子性,这时候就可以用到atomikos.笔者这里整合了一个spring和atomikos的demo,并且通过案例演示说明atomikos的作用. 准备工作 开发工具:idea 数据库:mysql , oracle 正文 源码地址: https://github.com/qw870602/atomikos 演示原理:通过在

  • springboot jta atomikos实现分布式事物管理

    这篇文章主要介绍了springboot jta atomikos实现分布式事物管理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 当项目在连接多个数据库时可能会发生事务问题,即一个库的事务不可能去操作另一个数据库的事务,这时就需要使用atomikos对数据库的事务进行统一的管理 第一步添加atomikos的依赖 <dependency> <groupId>org.springframework.boot</groupId&g

  • Spring系列之事物管理

    目录 前言 Spring事务抽象 Spring之编程式事物 声明式事物 事物失效的8种情况及解决办法 前言 我们都知道Spring给我们提供了很多抽象,比如我们在操作数据库的过程中,它为我们提供了事物方面的抽象,让我们可以非常方便的以事物方式操作数据库.不管你用JDBC.Mybatis.Hibernate等任何一种方式操作数据库,也不管你使用DataSource还是JTA的事物,Spring事物抽象管理都能很好的把他统一在一起.接下来看一下事物的抽象核心接口 Spring事务抽象 Platfor

  • SpringBoot整合atomikos实现跨库事务的详细方案

    目录 背景 方案设计 Maven配置 注册XA数据源 注册XA事务管理器 定义XA事务切面 配置XA事务日志 背景 框架之前完成了多数据源的动态切换及事务的处理,想更近一步提供一个简单的跨库事务处理功能,经过网上的搜索调研,大致有XA事务/SEGA事务/TCC事务等方案,因为业务主要涉及政府及企业且并发量不大,所以采用XA事务,虽然性能有所损失,但是可以保证数据的强一致性 方案设计 针对注册的数据源拷贝一份用于XA事务,使得本地事务和XA全局事务相互独立可选择的使用 Maven配置 引入atom

  • SpringBoot中整合Shiro实现权限管理的示例代码

    之前在 SSM 项目中使用过 shiro,发现 shiro 的权限管理做的真不错,但是在 SSM 项目中的配置太繁杂了,于是这次在 SpringBoot 中使用了 shiro,下面一起看看吧 一.简介 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理.使用Shiro的易于理解的API,您可以快速.轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序. 三个核心组件: 1.Subject 即"当前操作用户".但是,在 Shi

  • Redis实现分布式Session管理的机制详解

    一. Redis实现分布式Session管理 1. Memcached管理机制 2. Redis管理机制 1.redis的session管理是利用spring提供的session管理解决方案,将一个应用session交给Redis存储,整个应用中所有session的请求都会去redis中获取对应的session数据. 二. SpringBoot项目开发Session管理 1. 引入依赖pop.xml <!--springboot-redis--> <dependency> <

  • springboot中使用@Transactional注解事物不生效的坑

    一:在springboot中使用事物遇到的坑 1.我们知道spring中的事物分为两种:一种是编程式事物,一种是声明式事物.顾名思义,编程式事物是指通过代码去实现事物管理,这里不做过多说明.另一种是声明式事物,分为两种情况01:一种是通过传统xml方式配置,02:使用@Transaction注解方式配置,这是主要讲解的是通过注解方式配置.因为在springboot项目中,会自动配置DataSourceTransactionManager,我们只需要在对应的方法上或者类上加上@Transactio

  • SpringBoot使用Atomikos技术整合多数据源的实现

    Atomikos是一个为Java平台提供增值服务的并且开源类事务管理器,如果将事务统一注册到Atomikos中,则可以统一管理.常用于后台管理系统的多数据库操作. 多数据源的划分方式 方式: a.按包名 b.按注解区分 Springboot默认集成事务,只主要在方法上加上@Transactional即可,不需要开启@EnableTransactionManagement注解 如果多个数据库,则每个方法都需要单独设置事务管理器@Transactional(transactionManager =

  • MyBatis5中Spring集成MyBatis事物管理

    单独使用MyBatis对事物进行管理 前面MyBatis的文章有写过相关内容,这里继续写一个最简单的Demo,算是复习一下之前MyBatis的内容吧,先是建表,建立一个简单的Student表: create table student ( student_id int auto_increment, student_name varchar(20) not null, primary key(student_id) ) 建立实体类Student.java: public class Studen

  • Vue+SpringBoot开发V部落博客管理平台

    V部落是一个多用户博客管理平台,采用Vue+SpringBoot开发. 演示地址: http://45.77.146.32:8081/index.html 项目地址: https://github.com/lenve/VBlog 登陆页面 文章列表 发表文章 用户管理 栏目管理 数据统计 技术栈 后端技术栈 后端主要采用了: 1.SpringBoot 2.SpringSecurity 3.MyBatis 4.部分接口遵循Restful风格 5.MySQL 前端技术栈 前端主要采用了: 1.Vue

  • SpringBoot集成Zipkin实现分布式全链路监控

    Zipkin 简介 Zipkin is a distributed tracing system. It helps gather timing data needed to troubleshoot latency problems in service architectures. Features include both the collection and lookup of this data. If you have a trace ID in a log file, you ca

随机推荐