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 ...
随机推荐
- Largest Rectangle in a Histogram【单调栈模板】
Largest Rectangle in a Histogram 题目链接(点击)来源poj 2559 A histogram is a polygon composed of a sequence ...
- (三)POI-格式设置
原文链接:https://blog.csdn.net/class157/article/details/92800980 package com.java.poi; import org.apache ...
- 在Unix系统中执行可执行文件
这篇文章是我在一个叫做Charlotte数据挖掘的公众号上看到的文章,文首提到转载自"朱小厮的博客",当我今天执行一个自己编译的可执行文件后的运行阶段想到了这篇文章,直接一次成功. ...
- Docker数据管理与挂载管理
介绍如何在 Docker 内部以及容器之间管理数据:在容器中管理数据主要有两种方式:数据卷(Volumes).挂载主机目录 (Bind mounts) 镜像来源 [root@docker01 ~]# ...
- 国外一教授坦言,用这方法能迅速成为python程序员,但都不愿意说_编程小十
越来越多的人学习python,但你学习python用了多长的时间?#Python# 你知道如何才能迅速掌握并成为python程序员吗? 有这样的一位国外的教授说,要迅速成为python程序员,几乎 ...
- 基于node的前端项目编译时内存溢出问题
解决方法: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory JavaScript堆内存不足,这里说的 Jav ...
- docker镜像瘦身思路
docker镜像瘦身思路 一.简介 docker镜像太大,带来了以下几个问题: 存储开销 这块影响其实不算很大,因为对服务器磁盘来说,15GB的存储空间并不算大,除非用户服务器的磁盘空间很紧张 部署时 ...
- 尚硅谷maven视频教程笔记
07.尚硅谷_Maven_部署Maven核心程序.avi 第一步先安装jdk 第二步下载maven 特别需要注意的是maven不能存储在有中文和空格的目录下面 3.调试是否安装成功,在cmd中输入 m ...
- Python实用笔记 (22)面向对象编程——实例属性和类属性
由于Python是动态语言,根据类创建的实例可以任意绑定属性. 给实例绑定属性的方法是通过实例变量,或者通过self变量: class Student(object): def __init__(se ...
- DOM-BOM-EVENT(1)
1.DOM简介 DOM(Document Object Model)即文档对象模型,是HTML和XML文档的编程接口.它提供了对文档的结构化的表述,并定义了一种方式可以使得从程序中对该结构进行访问,从 ...