虽然现在微服务越来越流行,我们的系统随之也拆分出来好多的模块功能。这样做的目的其实就是为了弥补单体架构中存在的不足。随着微服务的拆分,肯定设计到分库分表,但这之中肯定设计到分布式事务。最典型的例子就是银行转账,比如银行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库

[AppleScript] 纯文本查看 复制代码
1
2
3
4
5
<font style="color:rgb(77, 77, 77)"><font face="&quot"><font style="font-size:16px"><!--分布式事务-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency></font></font></font>

2、配置数据源

3、配置类

最主要的配置

[AppleScript] 纯文本查看 复制代码
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="&quot"><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多数据源中的分布式事务的更多相关文章

  1. 3分钟搞定SpringBoot+Mybatis+druid多数据源和分布式事务

    文章来自: https://blog.csdn.net/qq_29242877/article/details/79033287 在一些复杂的应用开发中,一个应用可能会涉及到连接多个数据源,所谓多数据 ...

  2. springboot学习笔记:10.springboot+atomikos+mysql+mybatis+druid+分布式事务

    前言 上一篇文章我们整合了springboot+druid+mybatis+mysql+多数据源: 本篇文章大家主要跟随你们涛兄在上一届基础上配置一下多数据源情况下的分布式事务: 首先,到底啥是分布式 ...

  3. 二、springboot项目使用seata实现分布式事务

    所有文章 https://www.cnblogs.com/lay2017/p/12078232.html 正文 在上一篇文章中,我们简单地了解了一下什么是seata.它是来自阿里巴巴的内部项目不断地发 ...

  4. spring+hibernate管理多个数据源(非分布式事务)

    本文通过一个demo,介绍如何使用spring+hibernate管理多个数据源,注意,本文的事务管理并非之前博文介绍的分布式事务. 这个demo将使用两个事务管理器分别管理两个数据源.对于每一个独立 ...

  5. spring+mybatis管理多个数据源(非分布式事务)

    本文通过一个demo,介绍如何使用spring+mybatis管理多个数据源,注意,本文的事务管理并非之前博文介绍的分布式事务. 这个demo将使用两个事务管理器分别管理两个数据源.对于每一个独立的事 ...

  6. SpringBoot统一异常处理后TX-LCN分布式事务无法捕获异常进行回滚

    通常我们使用SpringBoot都会进行统一异常处理,例如写一个BaseController,在BaseController里进行统一异常处理,然后其他的Controller都继承BaseContro ...

  7. spring boot:shardingsphere+druid多数据源整合seata分布式事务(spring boot 2.3.3)

    一,为什么要给shardingsphere配置多数据源? 1,shardingjdbc默认接管了所有的数据源, 如果我们有多个非分表的库时,则最多只能设置一个为默认数据库, 其他的非分表数据库不能访问 ...

  8. 多数据源问题--Spring+Ibatis 访问多个数据源(非分布式事务)

    有的时候,我在一个工程中需要访问两个以上的数据源,尤其是在系统集成的时候,以下是我在系统集成的时候遇到的情况,我的工程的架构是:spring2.0+ibatis2.0+struts1.2. 数据库是o ...

  9. DDD~领域事件中使用分布式事务

    回到目录 对于一个聚合来说,它可能会被附加很多事件,这里我们叫它领域事务,因为一个聚会我们可以把它理解成一个领域,一个业务.对于领域事件不清楚的同学可以看看我的这篇文章<DDD~领域事件与事件总 ...

随机推荐

  1. 基于JWT的token认证机制

    1. 一个JWT实际上就是一个字符串,由三部分组成 头部,载荷,签名 头部:事描述类型,签名,算法等 可以被表示成一个JSON对象 载荷:存放有效信息的地方 包含三个部分 (1)标准注册中的声明-建议 ...

  2. How to .gitignore all files/folder in a folder, but not the folder itself?

    https://stackoverflow.com/questions/4250063/how-to-gitignore-all-files-folder-in-a-folder-but-not-th ...

  3. ajax上传图片到服务器简单操作

    前端: 通过Ajax方式上传文件,使用FormData进行Ajax请求.上传文件或图片时,要求的格式为enctype ="multipart/form-data"(以二进制格式上传 ...

  4. 浅谈JVM - 内存结构(二)- 虚拟机栈|凡酷

    2.1 定义 Java Virtual Machine Stacks(Java虚拟机栈) Java 虚拟机栈描述的是 Java 方法执行的内存模型,用于存储栈帧,是线程私有的,生命周期随着线程启动而产 ...

  5. MyBatis从入门到精通(第6章):MyBatis 高级查询->6.1.2高级结果映射之一对多映射

    jdk1.8.MyBatis3.4.6.MySQL数据库5.6.45.IntelliJ IDEA 2019.3.1 本章主要包含的内容为 MyBatis 的高级结果映射,主要处理数据库一对一.一对多的 ...

  6. 【C#并发】00概述

    摘自<C#并发编程经典实例>[美]Stephen Cleary 并发:同时做多件事情.终端用户利用并发功能,在输入数据库的同时相应用户输入.服务器应用并发,在处理第一个请求的同时响应第二个 ...

  7. ES6 find()

    Array.prototype.find() 返回数组中满足提供测试函数的第一个元素的值,否则返回undefined let b = blogs.find(function(e) => { re ...

  8. 关于vue内只要html元素的代码

    使用v-model v-text v-html vue会解析出入的html代码报错 则上传sku的description时需要html页面的代码 所以在description 所在的表单元素内加入 v ...

  9. java中 Spring 定时器定时任务Quartz的正确使用方法集配置

    定时任务我想大家都不默认,现在流行的框架spring就带了定时任何 我的个人网站(http://www.yzcopen.com)上用户上传的文件都是用这套定时任务执行定时清除 第一步:在applica ...

  10. CaptchaCodeManager

    package org.linlinjava.litemall.wx.service; import org.linlinjava.litemall.wx.dto.CaptchaItem; impor ...