SpringBoot2 整合JTA组件,多数据源事务管理
本文源码:GitHub·点这里 || GitEE·点这里
一、JTA组件简介
1、JTA基本概念
JTA即Java-Transaction-API,JTA允许应用程序执行分布式事务处理,即在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序对JTA的支持极大地增强了数据访问能力。
XA协议是数据库层面的一套分布式事务管理的规范,JTA是XA协议在Java中的实现,多个数据库或是消息厂商实现JTA接口,开发人员只需要调用SpringJTA接口即可实现JTA事务管理功能。
JTA事务比JDBC事务更强大。一个JTA事务可以有多个参与者,而一个JDBC事务则被限定在一个单一的数据库连接。下列任一个Java平台的组件都可以参与到一个JTA事务中
2、分布式事务
分布式事务(DistributedTransaction)包括事务管理器(TransactionManager)和一个或多个支持 XA 协议的资源管理器 ( Resource Manager )。
资源管理器是任意类型的持久化数据存储容器,例如在开发中常用的关系型数据库:MySQL,Oracle等,消息中间件RocketMQ、RabbitMQ等。
事务管理器提供事务声明,事务资源管理,同步,事务上下文传播等功能,并且负责着所有事务参与单元者的相互通讯的责任。JTA规范定义了事务管理器与其他事务参与者交互的接口,其他的事务参与者与事务管理器进行交互。
二、SpringBoot整合JTA
项目整体结构图
1、核心依赖
<!--SpringBoot核心依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--JTA组件核心依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
2、环境配置
这里jtaManager的配置,在日志输出中非常关键。
spring:
jta:
transaction-manager-id: jtaManager
# 数据源配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource
data01:
driverClassName: com.mysql.jdbc.Driver
dbUrl: jdbc:mysql://localhost:3306/data-one
username: root
password: 000000
data02:
driverClassName: com.mysql.jdbc.Driver
dbUrl: jdbc:mysql://localhost:3306/data-two
username: root
password: 000000
3、核心容器
这里两个数据库连接的配置手法都是一样的,可以在源码中自行下载阅读。基本思路都是把数据源交给JTA组件来统一管理,方便事务的通信。
数据源参数
@Component
@ConfigurationProperties(prefix = "spring.datasource.data01")
public class DruidOneParam {
private String dbUrl;
private String username;
private String password;
private String driverClassName;
}
JTA组件配置
package com.jta.source.conifg;
@Configuration
@MapperScan(basePackages = {"com.jta.source.mapper.one"},sqlSessionTemplateRef = "data01SqlSessionTemplate")
public class DruidOneConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(DruidOneConfig.class) ;
@Resource
private DruidOneParam druidOneParam ;
@Primary
@Bean("dataSourceOne")
public DataSource dataSourceOne () {
// 设置数据库连接
MysqlXADataSource mysqlXADataSource = new MysqlXADataSource();
mysqlXADataSource.setUrl(druidOneParam.getDbUrl());
mysqlXADataSource.setUser(druidOneParam.getUsername());
mysqlXADataSource.setPassword(druidOneParam.getPassword());
mysqlXADataSource.setPinGlobalTxToPhysicalConnection(true);
// 事务管理器
AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
atomikosDataSourceBean.setXaDataSource(mysqlXADataSource);
atomikosDataSourceBean.setUniqueResourceName("dataSourceOne");
return atomikosDataSourceBean;
}
@Primary
@Bean(name = "sqlSessionFactoryOne")
public SqlSessionFactory sqlSessionFactoryOne(
@Qualifier("dataSourceOne") DataSource dataSourceOne) throws Exception{
// 配置Session工厂
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSourceOne);
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sessionFactory.setMapperLocations(resolver.getResources("classpath*:/dataOneMapper/*.xml"));
return sessionFactory.getObject();
}
@Primary
@Bean(name = "data01SqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(
@Qualifier("sqlSessionFactoryOne") SqlSessionFactory sqlSessionFactory) {
// 配置Session模板
return new SqlSessionTemplate(sqlSessionFactory);
}
}
4、测试对比
这里通过两个方法测试结果做对比,在两个数据源之间进行数据操作时,只需要在接口方法加上@Transactional注解即可,这样保证数据在两个数据源间也可以保证一致性。
@Service
public class TransferServiceImpl implements TransferService {
@Resource
private UserAccount01Mapper userAccount01Mapper ;
@Resource
private UserAccount02Mapper userAccount02Mapper ;
@Override
public void transfer01() {
userAccount01Mapper.transfer("jack",100);
System.out.println("i="+1/0);
userAccount02Mapper.transfer("tom",100);
}
@Transactional
@Override
public void transfer02() {
userAccount01Mapper.transfer("jack",200);
System.out.println("i="+1/0);
userAccount02Mapper.transfer("tom",200);
}
}
三、JTA组件小结
在上面JTA实现多数据源的事务管理,使用方式还是相对简单,通过两阶段的提交,可以同时管理多个数据源的事务。但是暴露出的问题也非常明显,就是比较严重的性能问题,由于同时操作多个数据源,如果其中一个数据源获取数据的时间过长,会导致整个请求都非常的长,事务时间太长,锁数据的时间就会太长,自然就会导致低性能和低吞吐量。
因此在实际开发过程中,对性能要求比较高的系统很少使用JTA组件做事务管理。作为一个轻量级的分布式事务解决方案,在小的系统中还是值得推荐尝试的。
最后作为Java下的API,原理和用法还是值得学习一下,开阔眼界和思路。
四、源代码地址
GitHub·地址
https://github.com/cicadasmile/middle-ware-parent
GitEE·地址
https://gitee.com/cicadasmile/middle-ware-parent
推荐阅读:SpringBoot进阶系列
SpringBoot2 整合JTA组件,多数据源事务管理的更多相关文章
- SpringBoot2 整合Ehcache组件,轻量级缓存管理
本文源码:GitHub·点这里 || GitEE·点这里 一.Ehcache缓存简介 1.基础简介 EhCache是一个纯Java的进程内缓存框架,具有快速.上手简单等特点,是Hibernate中默认 ...
- spring+springmvc+mybatis+oracle+atomikos+jta实现多数据源事务管理
---恢复内容开始--- 在做项目过程中,遇到了需要一个项目中访问两个数据库的情况,发现使用常规的spring管理事务,导致事务不能正常回滚,因此,采用了jta+atomikos的分布式数据源方式 ...
- spring boot 或 spring 集成 atomikos jta 完成多数据源事务管理
前言:对于事务,spring 不提供自己的实现,只是定义了一个接口来供其他厂商实现,具体些的请看我的这篇文章: https://www.cnblogs.com/qiaoyutao/p/11289996 ...
- springbootdruidmybatismysql多数据源事务管理
springboot+druid+mybatis+mysql+多数据源事务管理 分布式事务在java中的解决方案就是JTA(即Java Transaction API):springboot官方提供了 ...
- springboot-jta-atomikos多数据源事务管理
背景 我们平时在用springboot开发时,要使用事务,只需要在方法上添加@Transaction注解即可,但这种方式只适用单数据源,在多数据源下就不再适用: 比如在多数据源下,我们在一个方法里执行 ...
- 传统Spring配置JTA 实现多数据源事务的统一管理
分布式事务是指事务的参与者.支持事务的服务器.资源管理器以及事务管理器分别位于分布系统的不同节点之上,在两个或多个网络计算机资源上访问并且更新数据,将两个或多个网络计算机的数据进行的多次操作作为一个整 ...
- spring JTA多数据源事务管理详细教程
<context:annotation-config /> <!-- 使用注解的包路径 --> <context:component-scan base-package= ...
- Spring整合JMS(四)——事务管理
原文链接:http://haohaoxuexi.iteye.com/blog/1983532 Spring提供了一个JmsTransactionManager用于对JMS ConnectionFact ...
- Spring整合JMS(四)——事务管理(转)
*注:别人那复制来的 Spring提供了一个JmsTransactionManager用于对JMS ConnectionFactory做事务管理.这将允许JMS应用利用Spring的事务管理特性.Jm ...
随机推荐
- Java中容易遗漏的小知识点( 一 )(为了和小白一样马上要考试的兄弟准备的,希望小白和大家高过不挂)
笔者csdn博客同文地址:https://blog.csdn.net/weixin_45791445/article/details/106597515 我是小康小白,一个平平无奇的Java小白.热爱 ...
- 详说tcp粘包和半包
tcp服务端和客户端建立连接后会长时间维持这个连接,用于互相传递数据,tcp是以流的方式传输数据的,就像一个水管里的水一样,从一头不断的流向另一头. 理想情况下,发送的数据包都是独立的, 现实要复杂一 ...
- vue 组件传参及跨域传参
可以完成跨组件传参的四种方式 // 1) localStorage:永久存储数据 // 2) sessionStorage:临时存储数据(刷新页面数据不重置,关闭再重新开启标签页数据重置) // 3) ...
- 传统声学模型之HMM和GMM
声学模型是指给定声学符号(音素)的情况下对音频特征建立的模型. 数学表达 用 \(X\) 表示音频特征向量 (观察向量),用 \(S\) 表示音素 (隐藏/内部状态),声学模型表示为 \(P(X|S) ...
- TreeMap实现
- 浅谈tkinter模块
目录 tkinter模块 tkinter模块简单使用 主窗口 Button按钮 Label标签 Text编辑框 Entry输入框 ListBox列表 RadioButton单选框 CheckButto ...
- hibernate快速入门示例
hibernate概述 hibernate是一个java的全自动ORM框架,它可以自动生成SQL语句.自动建表.自动执行,使用者可以不使用SQL完成数据的CRUD操作,同时它也是基于JPA规则的一种实 ...
- xpath实战
# 1.爬取58二手房信息import requests from lxml import etree #需求:爬取58二手房中的房源信息 if __name__ == '__main__': #爬取 ...
- python实现的udp-收发聊天器
构建思想:创建三个函数,最后一个函数调用前两个 1.创建发送函数-send() 2.创建接收函数-recv() 3.创建调用函数(主函数)-main() import socket def send( ...
- java语言进阶(六)_线程_同步
第一章 多线程 想要设计一个程序,边打游戏边听歌,怎么设计? 要解决上述问题,需要使用多进程或者多线程来解决. 1.1 并发与并行 并发:指两个或多个事件在同一个时间段内发生. 并行:指两个或多个事件 ...