spring boot 多数据源的XA事务(Druid+Atomikos)

spring-boot入门(七)atomikos+druid+多数据源下的分布式事务配置 spring-boot入门(七)atomikos+druid+多数据源下的分布式事务配置 本章内容是基于spring-boot入门(六)多数据源的基础之上进行的,如果还不了解多数据源怎么配置,请参考上一章节的内容。在上一章节的末尾我们遗留了一个问题:多数据源下的分布式事务问题。在分布式事务下我们需要使用JTA(Java Transaction API)事务来处理事务,保证事务的强一致性,即要成功... 阅读详情

介绍

在一个项目中,可能需要连接不同的数据库,那么就需要配置多数据源.
如果在一个操作中,需要请求不同的数据库来完成业务逻辑,那么就需要使用分布式事务来保证数据一致性

数据库配置

  • 数据库1 : jtm
SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS `person`;
CREATE TABLE `person` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SET FOREIGN_KEY_CHECKS=1;
  • 数据库2: jtm1
SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS `person`;
CREATE TABLE `person` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SET FOREIGN_KEY_CHECKS=1;

应用配置

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.6.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jta-atomikos</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.0</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

XA数据源配置类

package com.example.demo.conf;

import com.alibaba.druid.pool.xa.DruidXADataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
import javax.sql.XADataSource;

@Configuration
public class MyDataSourceAutoConfiguration {
    @Primary
    @Bean(name = "dataSource1")
    public DataSource dataSource1() {
        AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
        ds.setXaDataSource(xaDataSource1());
        return ds;
    }

    @Bean(name = "dataSource2")
    public DataSource dataSource2() {
        AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
        ds.setXaDataSource(xaDataSource2());
        return ds;
    }

    XADataSource xaDataSource1() {
        DruidXADataSource xaDataSource = new DruidXADataSource();
        xaDataSource.setUrl("jdbc:mysql://localhost:3306/jtm?useUnicode=true&characterEncoding=UTF8&useSSL=false");
        xaDataSource.setUsername("root");
        xaDataSource.setPassword("root");
        return xaDataSource;
    }

    XADataSource xaDataSource2() {
        DruidXADataSource xaDataSource = new DruidXADataSource();
        xaDataSource.setUrl("jdbc:mysql://localhost:3306/jtm1?useUnicode=true&characterEncoding=UTF8&useSSL=false");
        xaDataSource.setUsername("root");
        xaDataSource.setPassword("root");
        return xaDataSource;
    }

    @Bean("first")
    JdbcTemplate first(@Qualifier("dataSource1") DataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }

    @Bean("second")
    JdbcTemplate second(@Qualifier("dataSource2") DataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }
}

测试

MyController

package com.example.demo.controller;

import com.example.demo.service.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @Autowired
    MyService myService;
    @GetMapping("/my/test")
    public Object myTest(@RequestParam("a1") Integer a1, @RequestParam("a2") Integer a2) {
        myService.myTest(a1, a2);
        return "ok";
    }
}

MyService

package com.example.demo.service;

public interface MyService {
    void myTest(Integer a1, Integer a2);
}

MyServiceImpl

package com.example.demo.service.impl;

import com.example.demo.service.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyServiceImpl implements MyService {
    @Autowired
    @Qualifier("first")
    JdbcTemplate jdbcTemplate;

    @Autowired
    @Qualifier("second")
    JdbcTemplate jdbcTemplate1;

    @Transactional
    public void myTest(Integer a1, Integer a2) {
        jdbcTemplate.execute("INSERT INTO person(id, name, age) VALUES (" + a1 + ",'aaa', 18)");
        jdbcTemplate1.execute("INSERT INTO person(id, name, age) VALUES (" + a2 + ",'aaa', 18)");
    }
}

请求一

请求: http://localhost:8999/my/test?a1=1&a2=1
返回结果: ok
数据库结果:
- jtm
jtm数据库
- jtm1
jtm1数据库

请求二

请求 : http://localhost:8999/my/test?a1=11&a2=1
返回结果:

{
    "timestamp": 1512632326397,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "org.springframework.dao.DuplicateKeyException",
    "message": "StatementCallback; SQL [INSERT INTO person(id, name, age) VALUES (1,'aaa', 18)]; Duplicate entry '1' for key 'PRIMARY'; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'PRIMARY'",
    "path": "/my/test"
}

数据库结果:
- jtm
jtm数据库
- jtm1
jtm1数据库

Mybatis的XA实现

代码地址: Github

Spring Boot:mybatis-plus + atomikos + druid 实现不同实例数据库的多数据源配置和分布式事务管理 想到工作上可能会用到多数据源,但是自己在这方面并不是很熟悉,于是在网上查阅了很多文章,结果发现,网上的文章要么版本太老有些过时,要么用的不是mybatis-plus而是mybaits,要么步骤繁琐、需要自己手动编写aop切面代码,要么在同一service层方法中只能使用@Transactional实现单个数据源的事务管理控制,总是觉得有点不太完美,所以综合了以上文章的不足之处和可以借鉴之处,在这里总结出了一个万能的、可以适应多方面需求的多数据源配置方法,以满足相对完整的、代码简练的分布式事务控制需求。 一. 阅读详情

相关推荐

千云物流- 使用spring家族常见问题

2.0之前使用配置 2.0之后使用配置 第一种WebMvcConfigurer配置 第二种WebMvcConfigurer配置 注意事项 spring拦截器配置不生效

Hello Word 1429

Spring Boot 中的 XA 事务

在本文中,我们介绍了 Spring Boot 中的 XA 事务是什么,以及如何使用它。通过使用 Atomikos 事务管理器和 @Transactional 注解,我们可以轻松地实现 XA 事务,确保多个应用程序同时对同一个资源进行操作时的数据一致性和完整性。同时,我们还介绍了 XA 协议和两阶段提交协议等相关概念,以帮助读者更好地理解 XA 事务的实现原理。

程序猿徐师兄的博客 1650

事务—【02】SpringBoot使用JTA Atomikos实现多数据源事务管理

0. 前置知识 0.1 事务的一些基本概念 上篇说了事务的一些概念和Spring中的一些接口定义以及单数据源事务的实现具体的自己点下链接看吧 https://juejin.im/post/5e17013de51d453cbc4613a3 0.2 X/OPEN DTP模型 全称:X/Open Distributed Transaction Processing Reference Model,...

苡仁 3443

Springboot集成 Druid

Druid是一个开源的数据库连接池和SQL查询优化工具,用于提高应用程序对数据库的性能和可扩展性。主要提供的功能:数据库连接池、数据库连接池监控、SQL查询优化、数据源管理、防御SQL注入、统计和监控。注意:SpringBoot2.0默认是用com.zaxxer.hikari.HikariDataSource作为数据源。提示:以下是本篇文章正文内容,下面案例可供参考以上就是SpringBoot集成Druid数据库连接池工具,及简单的SpringBoot自动装配的原理。

qq_44896640的博客 6158

【万字长文】SpringBoot整合Atomikos实现多数据源分布式事务(提供Gitee源码)

在最近的实际开发的过程中,遇到了在多数据源的情况下要保证原子性的问题,这个问题当时遇到了也是思考了一段时间,后来通过搜集大量资料与学习,最后是采用了分布式事务来解决这个问题,在讲解之前,在我往期的博客提前搭好了一个SpringBoot整合MyBatis搭建MySQL多数据源的教程,本篇博客我是在原有的这个项目的基础之上进行的改造,主要新增了几个配置项进行实现的,大家可以先简单的看一下这篇文章!

黄团团的个人博客 2699

Spring Boot + Druid + Mybatis + Atomikos 配置多数据源 并支持分布式事务

本用例基于 Spring Boot + Druid + Mybatis 配置多数据源,并采用 JTA 实现分布式事务。

Seata架构篇 - XA模式

本文介绍Seata的XA事务模式。

The Secret 1318

jta:Springboot + Atomikos + Druid + Mysql 实现JTA分布式事务

jta Springboot + Atomikos + Druid + Mysql 实现JTA分布式事务 问题一:Druid 和 Mysql 版本的问题 问题二:Springtest 默认情况下事务回滚 Mysql对XA协议支持不好,有待看

分布式事务--XA 解决多个数据源操作

个人备忘事务(官方解释):是由一组sql语句组成的“逻辑处理单元”。事务具有如下四个属性,通常称为事务的ACID属性 : 1. 原子性(Atomicity): 事务是一个原子操作单元,要么都执行,要么都不执行。 2. 一致性(Consistent):在事务开始和完成时,数据都必须保持一致。 3. 隔离性(Isoation): 数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立

qq_16681279的博客 7858

【流复制环境PostgreSQL-14.1到PostgreSQL-16.1大版本升级】

PostgreSQL大版本会定期添加新特性,这些新特性通常会改变系统表的布局,但内部数据存储格式很少改变。pg_upgrade通过创建新的系统表和重用旧的用户数据文件来执行快速升级。pg_upgrade升级主要有三种用法:1、使用pg_upgrade拷贝升级。2、使用pg_upgrade链接升级(带有- -link选项),- -link较快,但是启动新版本后修改了数据文件,再启动旧版本可能数据损坏,回滚较麻烦,所以尽量避免使用link参数进行升级。

小怪兽的博客 2926

ZYNQ Linux下UIO中断配置避坑实录:从设备树修改到用户层测试(Vivado 2018.2)

本文详细解析了ZYNQ Linux下UIO中断配置的全流程,从设备树修改到用户层测试,特别针对Vivado 2018.2环境中的常见陷阱提供解决方案。内容涵盖中断号配置规则、用户空间中断处理程序编写以及性能优化技巧,帮助开发者高效实现硬件中断的用户空间控制。

weixin_31854867的博客 333

Springboot多数据源集成druid+atomikos,出现CommunicationsException错误:The client was disconnected by the server

Springboot集成多数据源事物就使用了atomikos框架,然后在线上发现报CommunicationsException异常的错误,因为晚上没有人使用,所以我猜是因为长时间没有连数据库导致的。

wien717651800的博客 1915

电流互感器的使用分析

有关电流互感器使用的注意事项,回头再看,耳目一新。

qq_46757048的博客 2万+

SpringBoot整合JTA

导读JTA,即Java Transaction API,JTA允许应用程序执行分布式事务处理——在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序的JTA支持极大地增强了数据...

码猿技术专栏 3208

深入浅出PWM:用示波器带你理解占空比与滤波效果

本文通过示波器实测,深入浅出地解析了PWM(脉宽调制)的核心原理。从占空比与平均电压的关系入手,详细演示了RC及有源滤波器如何将数字方波“翻译”为平滑模拟电压,并探讨了PWM-DAC的精度、响应速度等关键设计考量,为硬件调试与电路设计提供了实用的实践指导。

weixin_29292431的博客 345

“华为杯”研究生数学建模竞赛2020年-【华为杯】D题:无人机集群协同对抗(附获奖论文和MATLAB代码实现)

1.问题重述摘 要:本文针对非线性约束条件下红蓝双方无人机集群协同对抗的最优规划问题,结合贪婪队形、非线性规划、内点法、蒙特卡洛方法和全联立正交配置有限元法,构建了无人机集群协同对抗推演模型。,构建了。我们综合考虑了,和。首先分析红方在集群约束下的贪婪队形和拦截策略,然后我们基于内点法联合MATLAB和AMPL编程求解蓝方突防的非线性规划解,最后基于蒙特卡洛法对整个蓝方突防过程进行推演,得到突防概率图。通过推演,我们提出了两块的区域作为所求区域,并对蓝方的最优突防策略进行分析。

getusushu的博客 1550

在springboot中利用JTA做多数据源的事物回滚

JTA 实现原理 很多开发人员都会对 JTA 的内部工作机制感兴趣:我编写的代码没有任何与事务资源(如数据库连接)互动的代码,但是我的操作(数据库更新)却实实在在的被包含在了事务中,那 JTA 究竟是通过何种方式来实现这种透明性的呢? 要理解 JTA 的实现原理首先需要了解其架构:它包括事务管理器(Transaction Manager)和一个或多个支持 XA 协议的资源管理器 ( Reso...

zpflwy1314的博客 993

微店构造订单页面,自动化抢票

之前的文章写过微店抢票如何构造订单页面分析,这篇文章在之前的基础上,进行抢票。

猫敷雪 7202

spring boot + druid + mybatis + atomikos 多数据源配置 并支持分布式事务

文章目录一、综述1.1 项目说明1.2 项目结构二、配置多数据源并支持分布式事务2.1 导入基本依赖2.2 在yml中配置多数据源信息2.3 进行多数据源的配置1. 在启动类关闭springboot对数据源的自动化配置,由我们手动进行多数据源的配置2. 创建多数据源配置类`DataSourceFactory.java`, 手动配置多数据源3. 自定义sqlSessionTemplate的...

黑白影的博客 9018

【Zabbix实战之部署篇】Docker部署Zabbix+grafana监控平台

【Zabbix实战之部署篇】docker部署Zabbix+grafana监控平台

jks212454的博客 2577

ADB 安装教程:如何在 Windows、 Linux 上安装 Android Debug Bridge

本文介绍了在Windows和Linux系统上安装ADB(Android调试桥)的方法。对于Windows系统:1)从官网下载ADB工具并解压;2)通过命令提示符验证安装;3)配置环境变量以实现全局使用;4)再次验证全局ADB功能。Linux系统可通过包管理器直接安装(如Ubuntu使用apt,Fedora使用dnf),安装后同样需验证版本信息确认成功。两种系统安装完成后,都能通过"adb version"命令检查安装状态。

qq_53545309的博客 443

Spring Boot + MyBatis + Druid + Atomikos 多数据源分布式事务项目教程

Spring Boot + MyBatis + Druid + Atomikos 多数据源分布式事务项目教程 1. 项目介绍 本项目基于 Spring Boot、MyBatis、Druid 和 Atomikos,旨在配置动态多数据源并实现分布式事务。通过该项目,开发者可以轻松地在 Spring Boot 应用中集成多数据源,并确保在分布式环境下的数据一致性。 主要特性 动态多数据源切换:支持在运...

gitblog_00363的博客 1090

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

04_基于JTA+Druid多数据源+Atomikos实现单实例多数据源的事务控制

04_基于JTA+Druid多数据源+Atomikos实现分布式事务一. JTA+Druid+Atomickos的使用方式1.1 引入依赖1.2 增加配置1.3 druid数据源配置1.4 增加事务注解二. JTA+Atomikos分布式事务的源码分析2.1 创建分布式事务2.2 创建Datasource和Connection2.3 发送XA START2.4 发送XA END指令 一. JTA+Druid+Atomickos的使用方式 1.1 引入依赖 <dependency> <gr

爱喝咖啡的程序员的博客 1650

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

【SpringBoot框架篇】4.集成jta-atomikos实现分布式事务

springboot集成jta-atomikos实现分布式事务简介引入依赖修改配置文件添加配置读取类创建多数据源,管理事务数据持久化数据库DLL文件模拟事务回滚 简介 1.分布式事务 说到分布式事务,可以理解为,由于分布式而引起的事务不一致的问题。随着项目做大,模块拆分,数据库拆分。一次包含增删改操作数据库涉及到了更新两个不同物理节点的数据库,这样的数据库事务只能保证自己处理的部分的事务,但是整个...

皓亮君的博客 6127

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

分布式事务之xa:atomikos

须知:该博客是多数据源的事务问题,还未涉及微服务的事务 1、导入核心的依赖包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</a...

gzc_870301的博客 490

SpringBoot+Atomikos多数据源事务配置,以及日志打印控制。

前言:公司业务需求用到了多数据源,为了实现事务一致性所以选择使用了Atomikos。结合网上的资源做了一下配置,只保证了业务的实现具体原理没多做研究。 1·添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency>

qq_40353792的博客 2436
上一篇: spring boot 自定义校验注解
下一篇: spring boot 自定义请求参数解析注解
嘿嘿不错
博客等级 码龄11年 10粉丝 128原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值