本文源码: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注解即可,这样保证数据在两个数据源间也能够保障一致性。

@Servicepublic 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-parentGitEE·地址https://gitee.com/cicadasmile/middle-ware-parent

举荐浏览:SpringBoot进阶系列

序号文章题目
01Boot2 整合 shard-jdbc 中间件,实现数据分库分表
02Boot2 整合 JavaMail ,实现异步发送邮件性能
03Boot2 整合 RocketMQ ,实现申请异步解决
04Boot2 整合 Swagger2 ,构建接口治理界面
05Boot2 整合 QuartJob ,实现定时器实时治理
06Boot2 整合 Redis集群 ,实现音讯队列场景
07Boot2 整合 Dubbo框架 ,实现RPC服务近程调用
08Boot2 整合 ElasticSearch框架,实现高性能搜索引擎
09Boot2 整合 JWT 框架,解决Token跨域验证问题
10Boot2 整合 FastDFS 中间件,实现文件散布治理
11Boot2 整合 Shiro 框架,实现用户权限治理
12Boot2 整合 Security 框架,实现用户权限治理
13Boot2 整合 ClickHouse数据库,实现数据高性能查问剖析
14Boot2 整合 Drools规定引擎,实现高效的业务规定
15Boot2 整合 多数据源,配置MybatisPlus加强插件
16Boot2 整合 Zookeeper组件,治理架构中服务协调
17Boot2 整合Nacos组件,环境搭建和入门案例详解
18文件系统(01):基于Boot2框架,治理Excel和PDF
18文件系统(02):基于Boot2框架,治理Xml和CSV
19Boot2 整合 Kafka组件,利用案例和流程详解
20Boot2 整合 ElasticJob框架,定制化治理流程