SpringBoot多数据源中的分布式事务
虽然现在微服务越来越流行,我们的系统随之也拆分出来好多的模块功能。这样做的目的其实就是为了弥补单体架构中存在的不足。随着微服务的拆分,肯定设计到分库分表,但这之中肯定设计到分布式事务。最典型的例子就是银行转账,比如银行A给银行B转账500 块钱,流程肯定是银行A-500,银行B+500,在这个过程要么都成功,要么都成仁。首先银行A和银行B的数肯定是在不同的数据库,如果在转账的过程中,银行A首先-500库钱之后,在银行B+500的时候出现了问题,如果事务不回滚,那么就会出现500块钱丢失的问题,也就是出现了事务一致性问题。
JTA + Atomikos解决分布式事务
一、JTA
JTA(java Transaction API)是JavaEE 13 个开发规范之一。Java 事务API,允许应用程序执行分布式事务处理——在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序的JTA支持极大地增强了数据访问能力。事务最简单最直接的目的就是保证数据的有效性,数据的一致性。
二、Atomikos
Atomikos是一个为Java平台提供增值服务的并且开源类事务管理器。
工作原理:分布式事务包括事务管理器和支持XA的资源管理器。资源管理器就是我们的DB,事务管理器就是承担调节和控制所有参与DB所设计到的事务。
个人理解:Atomikos 获取到数据库的连接之后,会屏蔽数据库底层的事务控制,然后全部交给 Atomikos,进行统一的调度和控制。
接下来,我们简单的做一个基于 SpringBoot 的分布式事务控制。
1、首先我们要引入需要引入的maven库
|
1
2
3
4
5
|
<font style="color:rgb(77, 77, 77)"><font face="""><font style="font-size:16px"><!--分布式事务--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId></dependency></font></font></font> |
2、配置数据源
3、配置类
最主要的配置
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
<font style="color:rgb(77, 77, 77)"><font face="""><font style="font-size:16px">@Configuration@MapperScan(basePackages = "com.example.mapper.db1", sqlSessionFactoryRef = "db1SqlSessionFactory")public class DB1DataSourcesConfig { @Primary @Bean(name = "db1DataSource") public DataSource dataSource(DB1Config DB1Config) { // 设置数据库连接 MysqlXADataSource mysqlXADataSource = new MysqlXADataSource(); mysqlXADataSource.setUrl(DB1Config.getUrl_jdbc()); mysqlXADataSource.setUser(DB1Config.getUsername()); mysqlXADataSource.setPassword(DB1Config.getPassword()); mysqlXADataSource.setPinGlobalTxToPhysicalConnection(true); // 交给事务管理器进行管理 AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean(); atomikosDataSourceBean.setXaDataSource(mysqlXADataSource); atomikosDataSourceBean.setUniqueResourceName("db1DataSource"); return atomikosDataSourceBean; } @Primary @Bean(name = "db1SqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource); sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:/mapper/db1/*.xml")); org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(); configuration.setMapUnderscoreToCamelCase(true); sessionFactoryBean.setConfiguration(configuration); return sessionFactoryBean.getObject(); } @Primary @Bean(name = "db1SqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); }}</font></font></font> |
这样基本就配置完了,这里我只写了一个数据库的配置,另外一个同这个一样,就是数据库信息变了而已。
4、测试
这里设计到两个数据的修改,学生姓名和学生分数成绩,这两个数据分别存储在不同的数据库。我们通过接口先修改用户信息,接着再修改用户的分数信息。
没有修改前的数据
我们先没不加事务,先看下如果再修改分数的时候出现异常,用户信息会不会回滚回去。
结果
首先代码在39行报错,如果按照我们的逻辑,如果修改分数失败,那么相应的用户的年龄修改也是不成功的,但是结果显示用户的年龄还是被修改了,显然这个接口并没有被分布式事务所管理。

我们先把数据改回原来,然后我们再把事务加上,看还不会出现这种问题。(方法上加@Transactional注解即可)
结果
加了分布式事务之后,通过结果就可以看到,如果后面的结果出现了错误,前面的数据也是会进行回滚的,保证了事务的前后一致性,确保了数据的安全准确。
总结:以上就是 JTA + Atomikos 实现分布式事务的整个过程,相对实现功能来说还是比较简单的,以上的测试是基于单个的 SpringBoot 项目的,相对于真正的微服务来说,这样的方式我还没有进行测试,如果需要进行微服务之间的事务管理,也可以通过 mq 或者 dubbo 去进行事务的一致性管理。等以后研究了再来跟大家分享。
SpringBoot多数据源中的分布式事务的更多相关文章
- 3分钟搞定SpringBoot+Mybatis+druid多数据源和分布式事务
文章来自: https://blog.csdn.net/qq_29242877/article/details/79033287 在一些复杂的应用开发中,一个应用可能会涉及到连接多个数据源,所谓多数据 ...
- springboot学习笔记:10.springboot+atomikos+mysql+mybatis+druid+分布式事务
前言 上一篇文章我们整合了springboot+druid+mybatis+mysql+多数据源: 本篇文章大家主要跟随你们涛兄在上一届基础上配置一下多数据源情况下的分布式事务: 首先,到底啥是分布式 ...
- 二、springboot项目使用seata实现分布式事务
所有文章 https://www.cnblogs.com/lay2017/p/12078232.html 正文 在上一篇文章中,我们简单地了解了一下什么是seata.它是来自阿里巴巴的内部项目不断地发 ...
- spring+hibernate管理多个数据源(非分布式事务)
本文通过一个demo,介绍如何使用spring+hibernate管理多个数据源,注意,本文的事务管理并非之前博文介绍的分布式事务. 这个demo将使用两个事务管理器分别管理两个数据源.对于每一个独立 ...
- spring+mybatis管理多个数据源(非分布式事务)
本文通过一个demo,介绍如何使用spring+mybatis管理多个数据源,注意,本文的事务管理并非之前博文介绍的分布式事务. 这个demo将使用两个事务管理器分别管理两个数据源.对于每一个独立的事 ...
- SpringBoot统一异常处理后TX-LCN分布式事务无法捕获异常进行回滚
通常我们使用SpringBoot都会进行统一异常处理,例如写一个BaseController,在BaseController里进行统一异常处理,然后其他的Controller都继承BaseContro ...
- spring boot:shardingsphere+druid多数据源整合seata分布式事务(spring boot 2.3.3)
一,为什么要给shardingsphere配置多数据源? 1,shardingjdbc默认接管了所有的数据源, 如果我们有多个非分表的库时,则最多只能设置一个为默认数据库, 其他的非分表数据库不能访问 ...
- 多数据源问题--Spring+Ibatis 访问多个数据源(非分布式事务)
有的时候,我在一个工程中需要访问两个以上的数据源,尤其是在系统集成的时候,以下是我在系统集成的时候遇到的情况,我的工程的架构是:spring2.0+ibatis2.0+struts1.2. 数据库是o ...
- DDD~领域事件中使用分布式事务
回到目录 对于一个聚合来说,它可能会被附加很多事件,这里我们叫它领域事务,因为一个聚会我们可以把它理解成一个领域,一个业务.对于领域事件不清楚的同学可以看看我的这篇文章<DDD~领域事件与事件总 ...
随机推荐
- Xcode中SVN不能提交.a及其他文件
Xcode默认忽略的.a 文件.所以无法提交到svn服务器,但是很多第三方的库都有.a文件.所以还是必须提交到服务器. 搜索了一下解决方案: http://wpt205.blog.163.com/bl ...
- Web应用和web.xml文件
1.构建Web应用 手动构建一个Web应用: 在任意的目录小创建一个文件夹,例如webDemo 在第一步创建的文件夹中创建一个WEB-INF文件夹(注意大写); 随意找到一个Web应用,将其中的web ...
- javaweb学习——会话技术(一)
会话: 1.什么是会话:从打开一个浏览器,访问页面,到最终关闭浏览器的一个过程,就是一次会话. 2.会话的特点:包含多个请求,一次完整的会话是只针对一个用户. 3.会话机制:web中常用的技术,用来跟 ...
- c语言中对指向指针的指针的理解?
/************************************************************************* > File Name: ptr_to_pt ...
- ssh登录脚本
#!/usr/bin/expect set timeout 100 set passwd "your password" spawn shell expect "key& ...
- python函数中的参数(关键字参数,默认参数,位置参数,不定长参数)
默认参数:定义函数的时候给定变量一个默认值. def num(age=1): 位置参数:调用函数的时候根据定义函数时的形参位置和实参位置进行引用. 关键字参数:如果定义的函数中含有关键字参数,调用函数 ...
- 将iso mount 到nfs 目录问题
最近有个需求,需要在多台系统安装程序,安装文件是iso 格式的,最普通的办法就是拷贝到其它系统,然后mount loop 到本地目录. 但是比较麻烦,而且当前已经有一个nfs 服务端了,于是想出一个办 ...
- 如何使用keras加载下载好的数据集
https://blog.csdn.net/houchaoqun_xmu/article/details/78492718 [keras]解决 example 案例中 MNIST 数据集下载不了的问题 ...
- Android音视频处理之基于MediaCodec合并音视频
Android提供了一个MediaExtractor类,可以用来分离容器中的视频track和音频track,下面的例子展示了使用MediaExtractor和MediaMuxer来实现视频的换音: p ...
- LeetCode——376.摆动序列
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如, [1,7,4,9,2,5] 是一个摆动序列, ...