JTA分布式事务管理器
XA协议:是一种标准协议,允许事务管理器协调多个资源管理器,确保在分布式事务中的一致性和原子性。
JTA:是JavaEE规范中的一种,用于管理分布式事务的 API,提供了事务的控制和协调机制
Atomikos理解成JTA的实现
XA是JTA的基础(JTA实现了XA协议) Atomikos实现了JTA
Atomikos这种方式限定与单应用多数据源使用场景.
关于理论的一些:
当业务操作需要涉及到多个数据库时,这就可称为分布式事务处理.实现分布式事务处理的关键是采用一种手段保证事务涉及的所有数据库所做的全部动作要么全部生效,要买么全部回滚.
目前处理分布式事务的规范就是XA规范.
X/Open组织为分布式事务制定了的事务中间件与数据库之间的接口规范.这种规范就是XA规范.事务中间件用它来通知数据库事务开始,提交,回滚等
X/Open组织仅仅制定了分布式事务处理的XA规范,但具体的实现则由不同的数据库厂商自行提供.
对于大部分主流商业及开源数据库都提供了XA规范的驱动
分布式事务处理方法很多
2PC 两阶段提交:
成功示例:

失败示例:


`id` int NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`content` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`user_id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`age` int DEFAULT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@Configuration
@MapperScan(basePackages = {"com.example.demo5.mapper"},sqlSessionFactoryRef = "primarySqlSessionFactory")
public class DataSourceConfig1 {@Primary@Bean(name="primaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.primary")public DataSource primaryDataSource(){//return DataSourceBuilder.create().build();//return new HikariDataSource();return new DruidDataSource();}@Primary@Bean(name="primarySqlSessionFactory")public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean bean=new SqlSessionFactoryBean();bean.setDataSource(dataSource);bean.setTypeAliasesPackage("com.example.demo5.pojo");bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*Mapper.xml"));SqlSessionFactory sqlSessionFactory = bean.getObject();sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);//sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL);return sqlSessionFactory;}@Primary@Bean(name="primarySqlSessionTemplate")public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("primarySqlSessionFactory")SqlSessionFactory sqlSessionFactory){return new SqlSessionTemplate(sqlSessionFactory);}@Primary@Bean(name="primaryJdbcTemplate")public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource")DataSource dataSource){return new JdbcTemplate(dataSource);}@Primary@Bean(name="primaryTransactionManager")public DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource")DataSource dataSource){return new DataSourceTransactionManager(dataSource);}}
@Configuration
@MapperScan(basePackages = {"com.example.demo5.mapper2"},sqlSessionFactoryRef = "secondSqlSessionFactory")
public class DataSourceConfig2 {@Bean(name="secondDataSource")@ConfigurationProperties(prefix = "spring.datasource.second")public DataSource secondDataSource(){return DataSourceBuilder.create().build();}@Bean(name="secondSqlSessionFactory")public SqlSessionFactory secondSqlSessionFactory(@Qualifier("secondDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean bean=new SqlSessionFactoryBean();bean.setDataSource(dataSource);bean.setTypeAliasesPackage("com.example.demo5.pojo2");bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers2/*Mapper.xml"));SqlSessionFactory sqlSessionFactory = bean.getObject();sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);//sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL);return sqlSessionFactory;}@Bean(name="secondSqlSessionTemplate")public SqlSessionTemplate secondSqlSessionTemplate(@Qualifier("secondSqlSessionFactory")SqlSessionFactory sqlSessionFactory){return new SqlSessionTemplate(sqlSessionFactory);}@Bean(name="secondJdbcTemplate")public JdbcTemplate secondJdbcTemplate(@Qualifier("secondDataSource")DataSource dataSource){return new JdbcTemplate(dataSource);}@Bean(name="secondTransactionManager")public DataSourceTransactionManager secondTransactionManager(@Qualifier("secondDataSource")DataSource dataSource){return new DataSourceTransactionManager(dataSource);}
} 

实体类


service


serviceImpl


事务测试

但是这两个事务管理器无法满足分布式事务
就是说我要将A数据库和B数据库的操作放在一个事务中,无法满足
Atomikos的数据源必须是AtomikosDataSourceBean,因此配置的数据源必须是XADatasource
然后再使用AtomikosDataSourceBean包装它们


使用Atomikos
Atomikos的数据源必须是AtomikosDataSourceBean,因此配置数据源必须先使用XADatasource,
然后再使用AtomikosDataSourceBean包装他们.
将不同数据源对应的AtomikosDataSourceBean注入对应sqlSessionFactory
application.properties

两个配置文件
@Configuration
@MapperScan(basePackages = {"com.example.demo5.mapper"},sqlSessionFactoryRef = "primarySqlSessionFactory")
public class DataSourceConfig1 {// @Primary@Bean(name="primary")@ConfigurationProperties(prefix = "spring.datasource.primary")public XADataSource primary(){//MysqlXADataSource mysqlXADataSource = new MysqlXADataSource();//application.properties中的要与他里面的属性对应//return mysqlXADataSource;DruidXADataSource druidXADataSource=new DruidXADataSource();return druidXADataSource;}@Bean(name="primaryDataSource")@Primarypublic DataSource primaryDataSource(){AtomikosDataSourceBean atomikosDataSourceBean=new AtomikosDataSourceBean();atomikosDataSourceBean.setXaDataSource(primary());atomikosDataSourceBean.setMaxPoolSize(20);atomikosDataSourceBean.setUniqueResourceName("mysqlDs1");//取个唯一名字return atomikosDataSourceBean;}@Primary@Bean(name="primarySqlSessionFactory")public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean bean=new SqlSessionFactoryBean();bean.setDataSource(dataSource);bean.setTypeAliasesPackage("com.example.demo5.pojo");bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*Mapper.xml"));SqlSessionFactory sqlSessionFactory = bean.getObject();sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);//sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL);return sqlSessionFactory;}@Primary@Bean(name="primarySqlSessionTemplate")public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("primarySqlSessionFactory")SqlSessionFactory sqlSessionFactory){return new SqlSessionTemplate(sqlSessionFactory);}@Primary@Bean(name="primaryJdbcTemplate")public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource")DataSource dataSource){return new JdbcTemplate(dataSource);}//使用JTA全局事务管理器后,不要再自定义事务管理器
// @Primary
// @Bean(name="primaryTransactionManager")
// public DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource")DataSource dataSource){
// return new DataSourceTransactionManager(dataSource);
// }} @Configuration
@MapperScan(basePackages = {"com.example.demo5.mapper2"},sqlSessionFactoryRef = "secondSqlSessionFactory")
public class DataSourceConfig2 {// @Primary@Bean(name="second")@ConfigurationProperties(prefix = "spring.datasource.second")public XADataSource second(){
// MysqlXADataSource mysqlXADataSource = new MysqlXADataSource();//application.properties中的要与他里面的属性对应
//
// return mysqlXADataSource;DruidXADataSource druidXADataSource=new DruidXADataSource();return druidXADataSource;}@Bean(name="secondDataSource")public DataSource secondDataSource(){AtomikosDataSourceBean atomikosDataSourceBean=new AtomikosDataSourceBean();atomikosDataSourceBean.setXaDataSource(second());atomikosDataSourceBean.setMaxPoolSize(20);atomikosDataSourceBean.setUniqueResourceName("mysqlDs2");//取个唯一名字return atomikosDataSourceBean;}@Bean(name="secondSqlSessionFactory")public SqlSessionFactory secondSqlSessionFactory(@Qualifier("secondDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean bean=new SqlSessionFactoryBean();bean.setDataSource(dataSource);bean.setTypeAliasesPackage("com.example.demo5.pojo2");bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers2/*Mapper.xml"));SqlSessionFactory sqlSessionFactory = bean.getObject();sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);//sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL);return sqlSessionFactory;}@Bean(name="secondSqlSessionTemplate")public SqlSessionTemplate secondSqlSessionTemplate(@Qualifier("secondSqlSessionFactory")SqlSessionFactory sqlSessionFactory){return new SqlSessionTemplate(sqlSessionFactory);}@Bean(name="secondJdbcTemplate")public JdbcTemplate secondJdbcTemplate(@Qualifier("secondDataSource")DataSource dataSource){return new JdbcTemplate(dataSource);}// @Bean(name="secondTransactionManager")
// public DataSourceTransactionManager secondTransactionManager(@Qualifier("secondDataSource")DataSource dataSource){
// return new DataSourceTransactionManager(dataSource);
// }
} 
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.0</version></dependency><!--stomikos--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jta-atomikos</artifactId></dependency><!--德鲁伊--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.15</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId> <!-- <scope>runtime</scope>使用MysqlXADataSource的话把运行时去掉,不然找不到 不用可以恢复运行时--></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>3.0.2</version><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build>
相关文章:
JTA分布式事务管理器
XA协议:是一种标准协议,允许事务管理器协调多个资源管理器,确保在分布式事务中的一致性和原子性。 JTA:是JavaEE规范中的一种,用于管理分布式事务的 API,提供了事务的控制和协调机制 Atomikos理解成JTA的实现 XA是JTA的基础(JT…...
晨控CK-GW08系列网关控制器与CODESYS软件MODBUSTCP通讯手册
晨控CK-GW08系列是一款支持标准工业通讯协议ModbusTCP的网关控制器,方便用户集成到PLC等控制系统中。系统还集成了8路读写接口,用户可通过通信接口使用Modbus TCP协议对8路读写接口所连接的读卡器进行相对独立的读写操作。 晨控CK-GW08系列网关控制器适用于本公司多…...
读书笔记——labuladong算法笔记
读书笔记——labuladong算法笔记 序言计算机算法世界观计算机算法方法论二叉树遍历广度遍历BFS二叉树的前中后序遍历回溯算法动态规划算法二分搜索算法 其他算法滑动窗口双指针Union-Find算法 序言 labuladong算法笔记是一本讲解算法题求解技巧的书。本次读书笔记为2023年8月第…...
Linux中阶教程:bash shell基础
文章目录 输入输出赋值和计算条件判断函数for 循环数组及其遍历其他控制语句 输入输出 echo表示打印字符串;read表示获取用户输入;$用于引用变量。 # test1.sh bash中用#进行单行注释 echo "input your name:" read user_name echo "h…...
Golang 编译原理
简介 Golang(Go语言)是一种开源的编程语言,由Google开发并于2009年首次发布。它具备高效、可靠的特性,被广泛应用于云计算、分布式系统、网络服务等领域。Golang的编译原理是理解和掌握这门语言的重要基础之一。本文将介绍Golang…...
基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别 计算机竞赛
文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…...
计算机视觉基础——基于yolov5-face算法的车牌检测
文章目录 车牌检测算法检测实现1.环境布置2.数据处理2.1 CCPD数据集介绍2.1.1 ccpd2019及20202.1.2 文件名字解析 2.2数据集处理2.2.1 CCPD数据处理2.2.2 CPRD数据集处理 2.3 检测算法2.3.1 数据配置car_plate.yaml2.3.2 模型配置2.3.3 train.py2.3.4 训练结果 2.4 部署2.4.1 p…...
【好书推荐】AI时代架构师修炼之道:ChatGPT让架构师插上翅膀
目录 前言 ChatGPT对架构师工作的帮助 快速理解和分析需求 提供代码建议和解决方案 辅助系统设计和优化 提高团队协作效率 如何使用ChatGPT提高架构师工作效率 了解用户需求和分析问题 编码实践和问题解决 系统设计和优化建议 团队协作和沟通效率提升 知识管理和文…...
全局代理和局部代理的区别
在计算机领域中,代理是一种常见的网络技术,它可以帮助用户更好地控制网络访问和数据传输。代理可以分为全局代理和局部代理两种,它们有着不同的作用和适用场景。 一、全局代理 全局代理指的是在系统级别设置的代理,它可以代理所…...
基于EPICS stream模块的直流电源的IOC控制程序实例
本实例程序实现了对优利德UDP6720系列直流电源的网络控制和访问,先在此介绍这个项目中使用的硬件: 1、UDP6721直流电源:受控设备 2、moxa串口服务器5150:将UDP6721直流电源设备串口连接转成网络连接 3、香橙派Zero3:运…...
Unity3D ECS架构适合作为主架构还是局部架构
前言 前言 Unity3D是一款广泛应用于游戏开发的跨平台游戏引擎,提供了丰富的功能和工具来简化游戏开发的过程。而Entity-Component-System(ECS)架构则是一种面向数据的设计模式,它将游戏对象(Entity)分解为…...
从零开始的目标检测和关键点检测(三):训练一个Glue的RTMPose模型
从零开始的目标检测和关键点检测(三):训练一个Glue的RTMPose模型 一、重写config文件二、开始训练三、ncnn部署 从零开始的目标检测和关键点检测(一):用labelme标注数据集 从零开始的目标检测和关键点检测…...
Qt6 中弹出消息框,一段时间后自动退出
以下代码功能,弹出模态消息框,然后,等待 3 秒,消息框自动退出 QMessageBox msgbox;msgbox.setText("sleep 3s");QTimer::singleShot(3000, &msgbox, &QMessageBox::close);msgbox.exec();...
elementUI树节点全选,反选,半选状态
// <template>部分 <div class"check-block"><el-divider></el-divider><el-checkbox :indeterminate"indeterminate" v-model"checkAll" change"handleCheckAllChange">全选</el-checkbox><e…...
Kafka、RabbitMQ、RocketMQ中间件的对比
消息中间件现在有不少,网上很多文章都对其做过对比,在这我对其做进一步总结与整理。 RocketMQ 淘宝内部的交易系统使用了淘宝自主研发的Notify消息中间件,使用Mysql作为消息存储媒介,可完全水平扩容,为了进一步降低成…...
Mac 创建并使用 .zshrc 文件
1,打开终端输入指令 touch .zshrc 2,你可能希望将 .bash_profile 文件中的内容复制到 .zshrc 文件中,那建议复制过来。 3,使用 .zshrc 文件 执行以下指令: source .zshrc 注:以后希望使用 .bash_prof…...
Unity3D移动开发如何依据性能选择Shader
前言 在Unity3D移动开发中,选择合适的Shader是非常重要的,它直接影响到游戏的性能和画面效果。本文将介绍如何依据性能选择Shader,并给出相应的技术详解以及代码实现。 对惹,这里有一个游戏开发交流小组,希望大家可以…...
基于stm32F4的智能宠物喂食器的设计:LVGL界面、定时喂食喂水通风
宠物喂食器 一、功能设计二、元器件选型三、UI设计四、原理图设计五、源代码设计六、成品展示 实物链接:https://m.tb.cn/h.5iCUX6H?tkPL65WXCEipQ CZ3457 一、功能设计 1、设计一个触摸屏作为人机交互 2、通过触摸屏设置时间定时喂食喂水通风 3、获取当前水槽的…...
jumpserver堡垒机docker方式安装部署
1、环境要求 请先自行创建 数据库 和 Redis, 版本要求参考上面环境要求说明 mysql>5.7 redis >5.0 2、创建数据库 mysql: create database jumpserver default charset utf8; GRANT ALL PRIVILEGES ON jumpserver.* TO jumpserver% IDENTIFIED BY nu4x599…...
在基于亚马逊云科技的湖仓一体架构上构建数据血缘的探索和实践
背景介绍 随着大数据技术的进步,企业和组织越来越依赖数据驱动的决策。数据的质量、来源及其流动性因此显得非常关键。数据血缘分析为我们提供了一种追踪数据从起点到终点的方法,有助于理解数据如何被转换和消费,同时对数据治理和合规性起到关…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...
