SpringCloud Alibaba - Seata 四种分布式事务解决方案(XA、AT)+ 实践部署(上)

这篇具有很好参考价值的文章主要介绍了SpringCloud Alibaba - Seata 四种分布式事务解决方案(XA、AT)+ 实践部署(上)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、Seata 分布式事务解决方案

1.1、XA 模式

1.1.1、XA模式理论

第一阶段:

第二阶段:

1.1.2、Seata 框架中的 XA 模式

第一阶段:

第二阶段:

1.1.3、XA 模式的优缺点

1.2.4、实现Seata 的 XA 模式

a)修改 application 文件(每一个参与事务的微服务)

b)给发起全局事务中的入口方法添加 @GlobalTransactional 注解

c)重启服务并测试

1.2、AT 模式

1.2.1、AT 模式理论

第一阶段:

第二阶段:

问题:XA模式 和 AT模式 的区别?

1.2.2、AT 模式脏写问题

1.2.3、解决办法:写隔离

1.2.4、AT 模式的优缺点

1.2.5、实现 AT 模式

a)建表

b)修改 application.yml 文件

c)重启服务并测试


一、Seata 分布式事务解决方案


1.1、XA 模式

1.1.1、XA模式理论

XA 模式是 X/Open 组织定义的一个分布式事务处理的标准,可以认为是分布式事务领域最早的标准了,所以几乎所有主流的数据库(mysql、oracle......)都是实现了这种标准. 换言之,这些数据库内部已经能够基于 XA 模式实现分布式事务了.

这种模式把分布式定义成了以下两个阶段

第一阶段:

这一阶段也叫做准备阶段,事务协调者 会向 资源管理器 发起一个准备的请求,也就是告诉他:“你可以去执行业务 sql 了啊,但是执行完了以后不可以提交!”. 随后,资源管理器 就执行数据库业务,然后将执行结果告诉 事务协调者(执行成功了,就是就绪状态;失败了,就是 fail 状态),这样 事务协调者 就可以根据结果判断下一个阶段要干什么.

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

第二阶段:

事务协调者收到 RM 的反馈之后,就会进行判断.  如果都执行成功了,就通知这些 RM:“你们可以提交了啊”,然后 RM 收到请求,就把事务提交了,整个事务也就结束了;如果有任意一个服务执行失败了,那么事务协调者就会通知这些RM,让他们全部回滚.

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

可以看出 XA 模式是一种强一致性的事务,软可用性,因为事务没有提交的时候,拿不到数据库锁,是不能进行其他操作的.

1.1.2、Seata 框架中的 XA 模式

Seata 的 XA 模式和上述讲的 XA 模式大体相似,只是多了一个 TM 的概念. 如下图

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

第一阶段:

Seata 实际上就是多了一个 TM 的概念, 也就是事务管理者. TM 一上来就是要去注册全局事务,作为分布式事务的入口,接下来就会去调用各个分支事务.  每个分支事务中又有一个 RM,RM 就回去 TC 里面注册分支事务,然后执行业务 sql,但是执行完后不能提交,只是去报告一下事务的状态.  到此,第一阶段结束.

第二阶段:

TM 这里的入口方法执行完了以后,就要去告诉 TC 说:“我这边执行完了,接下来就看你那边的情况了~”. 随后 TC 就会去检查各个分支事务报告的状态,然后向 RM 发送一个信号——如果第一阶段都执行成功了,那么就提交,反之,则进行回滚.   RM 收到信号之后就可以进行 提交/回滚 事务了.

1.1.3、XA 模式的优缺点

优点:

1. 支持强一致:执行完业务 sql 以后,不进行提交事务,而是等到 TC 协调完后,在进行 提交/回滚. 

2. 实现起来简单:因为数据库本身就支持 XA 模式,Seata 只是在数据库的 XA 模式上做了一层简单的封装.  如果只看核心部分,就没什么差别了.

缺点:

1. 弱可用性,性能差:第一阶段不提交,等待第二阶段才提交,这个过程中会占用数据库锁(相当于对系统资源的一种浪费).  一旦分支事务特别多的情况下,业务耗时就会很久.

2. 依赖数据库底层实现:虽然用起来简单了,但是如果我用的不是 mysql 这种关系型数据库,而是 redis 这种非关系型数据库就不行了.

1.2.4、实现Seata 的 XA 模式

a)修改 application 文件(每一个参与事务的微服务)

开启 seata 的 XA 模式

seata:
  data-source-proxy-mode: XA # 开启数据源代理的XA模式
b)给发起全局事务中的入口方法添加 @GlobalTransactional 注解

当前案例的全局事务入口是 订单服务中的 创建订单的 create 方法(案例架构如下图).

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

这里只需要在 create 方法上添加 @GlobalTransactional 注解即可

    @Override
    @GlobalTransactional
    public Long create(Order order) {
        // 创建订单
        orderMapper.insert(order);
        try {
            // 扣用户余额
            accountClient.deduct(order.getUserId(), order.getMoney());
            // 扣库存
            storageClient.deduct(order.getCommodityCode(), order.getCount());
        } catch (FeignException e) {
            log.error("下单失败,原因:{}", e.contentUTF8(), e);
            throw new RuntimeException(e.contentUTF8(), e);
        }
        return order.getId();
    }
c)重启服务并测试

Ps:这里不要忘了先启动 Nacos 和 TC 服务.

以下分别为用户余额和库存数量.

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

1. 这里使用 Postman 发送以下请求(减少 9 个库存数量,用户余额减少 200)

http://localhost:8082/order?userId=user202103032042012&commodityCode=100202003032041&count=9&money=200

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

2. 随后可以看到订单微服务返回 500 错误.

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

在扣款微服务中,先进行了扣款业务,但是随后 rm 又执行了回滚

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

在库存微服务中,可以看到扣减失败.

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

最后观察数据库中数据,可以看到事务已经回滚如初.

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

1.2、AT 模式

1.2.1、AT 模式理论

AT 模模式也是分阶段性提交的事务模型. 他的出现正式为了解决 XA 模式中资源锁定周期过长的一个缺陷.

AT 模式也分为两个阶段

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

第一阶段:

TM 去开启全局事务,作为分布式事务的入口,接着又会调用每一个分支事务 ,然后每个分支事务里的 rm 都会去注册分支事务,并执行本地的业务 sql,然后直接提交(这里就和 XA 不一样了). 因此 AT 模式就不需要像 XA 那样锁定资源,性能上要优于 XA 模式.

这里直接提交,万一有人失败了呢,没办法回滚不就导致状态不一致了吗?

实际上 AT 模式在执行 sql 之前,rm 会给当前数据生成一个快照,这个快照的名字叫 “undo log”,这就像是 redis 中 RDB 持久化时也会生成快照,那么即使服务重启,也可以根据快照恢复数据.  那么这样就即使有分支事务执行 sql 的时候失败了,也可以根据快照恢复如初,大胆提交就对了.

第二阶段:

TM 看到业务结束了,就会去通知 TC,那么 TC 就会判断是提交还是回滚.  如果分支事务的状态都是成功的,那就可以把第一阶段准备的快照给删了(删快照这个动作是异步的,因为第一阶段都成功了,也提交了,后面的事情就可以用一个线程独立去做,提高了效率).  如果第一阶段有人失败了,就要基于 undo log 恢复数据,恢复以后这个 log 也就没用了,最后也会删除.

问题:XA模式 和 AT模式 的区别?

1. XA模式在第一阶段的时候不会进行事务的提交,而 AT 模式执行完业务 sql 之后会立即提交事务,不会锁定资源,因此性能会好一些.

2. XA 依赖于数据库的机制来做回滚,而 AT 模式因为已经提交了,就不能回滚,他是通过给自己生成快照的方式来实现数据的恢复.

3. XA 模式是强一致,而 AT 是最终一致,因为 AT 在业务 sql 执行之后直接提交了,有人失败,有人成功,那么这个时候状态肯定是不一致的,也就是一个软状态,只有在第二阶段,基于快照恢复了数据,才能到达一个最终一致的效果.

1.2.2、AT 模式脏写问题

AT 模式在第一阶段执行完业务 sql 以后会直接提交,那么资源锁定的周期就比较短,效率高,但也正因为他提前释放了锁,就导致在高并发的场景下,会出现安全问题~

例如我这里有一个用户余额表,里面记录了 money 字段,表示余额. 

  1. 现在有一个线程开启了事务1,首先他会去获取数据库锁,接着生成快照(money = 100),然后执行业务 sql(把 money 值改成 90),最后提交事务,锁也就释放了. 
  2. 此时,另一个线程开启了 事务2 ,拿到锁以后保存快照(money = 90),执行业务 sql(把 money 值改成 80),最后提交释放锁.

到了第二阶段,假如说 事务1 要进行回滚(通过快照恢复数据),但是 事务1 的快照数据 money = 100!这个时候就出问题了,恢复了以后相当于 事务2 这哥们啥也没做. 这就是所谓的脏写问题.

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

1.2.3、解决办法:写隔离

上述过程出现的问题,归根结底还是隔离性的原因,如果第一阶段和第二阶段整体都是一个锁定状态,别人根本无法插入进来,因此 AT 模式就引入了一个东西叫 “全局锁”.

Ps:全局锁由 TC 来控制,用来记录当前哪个事务在操作哪种表的哪一行数据. 这张表了主要有 事务id、表名字、pk主键(记录这张表的哪一行数据).

  1. 有了全局锁,那么在刚刚上述栗子的 事务1中,执行完业务 sql 就会去获取全局锁,就表明这张表的这行数据是我 事务1 才能拥有的,此时就可以大胆的提交事务. 
  2. 当 事务2 执行完业务 sql 之后,也尝试去获取全局锁,但是由于 事务1 已经获取了,因此 事务2 就只能阻塞等待 事务1 释放锁.  事务1 想要释放全局锁得等到第二阶段结束,但是现在 事务2 又持有 DB 锁,事务1 也拿不到 DB 锁,因此事务就互相等待,直到 事务2 等待超时,就会进行回滚并释放 DB 锁.

这样也就实现了 事务1 在执行第一阶段和第二阶段的时候,任何人都不能来执行,起到了很好的 隔离效果.

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

问题一:有人可能就会说,那这不跟 XA  模式一样了?也锁定资源,这样别人也无法访问,效率不久下降了么?

这里实际上是有一个 锁粒度 上的差别.  XA 模式中是数据库锁不释放,意味着任何人都不能访问你这数据库的数据,而 AT 中的全局锁只是不能任何人操作这个表中的某一行数据,也就是说,同样是 account 表,你可以修改这张表其他所有不是余额的字段.  因此效率上还是高很多的.

问题二:有人可能就会说,隔离不彻底啊,可能有一种极端情况,就是在修改 money 的过程中,有一个其他 非Seata 管理的事务 也来修改 money 字段,这时候人家又不用获取全局锁,也可能出现脏写的问题

确实有可能,但是可能性非常低,有以下两个原因:

  1. 全局事务大多数情况下都是成功的,比如我这边转账,大多数情况下我不能明知道钱不够还去转超额的钱吧,那么第二阶段几乎就不会回滚. 
  2. 分布式事务耗时本来就长,或者说并发本来就比较低,像这种见缝插针的事务就更少见了.

但即使概论低,Seata 也还是考虑这种情况的. Seata 在管理的事务的时候,是保存了两个快照的,第一个是更新前的快照(money = 100),另一个是更新后的快照(money = 90). 在 Seata 管理的 事务1 执行到第二阶段的时候,他就会去对比数据库中的字段值 和 after-image(更新后的快照)是否一致,如果不一致,就知道其中有人动了手脚,此时他可能就会发一个短信、邮件、电话告诉你,需要人工介入了.

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

1.2.4、AT 模式的优缺点

优点:

高性能:第一阶段完成后直接提交,释放资源比较早,数据库的锁定时间短.

写隔离:利用全局锁机制,不仅实现了隔离,性能也依旧维持.

使用简单,无代码侵入:Seata 框架自动完成回滚和提交.

缺点:

软状态:由于第一阶段执行业务 sql 可能有人成功有人失败,并且已经提交,这种情况下,并没有达成一致,只有第二阶段快照恢复才最终一致.

影响性能:虽然相比 XA模式,性能要好很多,但是框架的快照功能多多少少都会影响一点性能.

1.2.5、实现 AT 模式

a)建表

AT 模式下会引入全局锁,因此需要 lock_table 表来记录(在 TC 服务关联的数据库中创建).

DROP TABLE IF EXISTS `lock_table`;
CREATE TABLE `lock_table`  (
  `row_key` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `xid` varchar(96) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `transaction_id` bigint(20) NULL DEFAULT NULL,
  `branch_id` bigint(20) NOT NULL,
  `resource_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `table_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `pk` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `gmt_create` datetime NULL DEFAULT NULL,
  `gmt_modified` datetime NULL DEFAULT NULL,
  PRIMARY KEY (`row_key`) USING BTREE,
  INDEX `idx_branch_id`(`branch_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

AT 模式还需要保存快照,因此需要 undo_log 表来记录(在 微服务 关联的数据库中导入).

DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log`  (
  `branch_id` bigint(20) NOT NULL COMMENT 'branch transaction id',
  `xid` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'global transaction id',
  `context` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'undo_log context,such as serialization',
  `rollback_info` longblob NOT NULL COMMENT 'rollback info',
  `log_status` int(11) NOT NULL COMMENT '0:normal status,1:defense status',
  `log_created` datetime(6) NOT NULL COMMENT 'create datetime',
  `log_modified` datetime(6) NOT NULL COMMENT 'modify datetime',
  UNIQUE INDEX `ux_undo_log`(`xid`, `branch_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 'AT transaction mode undo table' ROW_FORMAT = Compact;
b)修改 application.yml 文件

将事务模式修改为 AT 模式即可.

seata:
  data-source-proxy-mode: AT # 开启数据源代理的AT模式
c)重启服务并测试

 以下分别为用户余额和库存数量.

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

1. 这里使用 Postman 发送以下请求(减少 9 个库存数量,用户余额减少 200)

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

2. 随后可以看到订单微服务返回 500 错误.

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

3. 扣款服务中进行扣款业务,最后回滚

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

4. 检查数据库数据回滚成功~

 分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring

分布式事务seata,SpringCloud & Alibaba,面试总结,spring cloud,分布式,spring文章来源地址https://www.toymoban.com/news/detail-851324.html

到了这里,关于SpringCloud Alibaba - Seata 四种分布式事务解决方案(XA、AT)+ 实践部署(上)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微服务13-Seata的四种分布式事务模式

    XA模式分为两种情况 : 提交成功: 提交失败: 具有强一致性seata相当于是在RM上做了一层封装; XA模式 优点 : 1.事务的强一致性,只要有失败的,TC事务协调者就会发送信息让RM回滚——满足ACID原则 2.没有代码侵入,常用数据库都支持 缺点 : 1.第一阶段就要锁定数据库资源

    2024年02月07日
    浏览(43)
  • Spring Cloud Alibaba全家桶(九)——分布式事务组件Seata

    本文小新为大家带来 分布式事务组件Seata 相关知识,具体内容包括 分布式事务简介 (包括: 事务简介 , 本地事务 , 分布式事务典型场景 , 分布式事务理论基础 , 分布式事务解决方案 ), 分布式事务Seata使用 (包括: Seata是什么 , Seata的三大角色 , Seata的设计思路

    2024年02月03日
    浏览(61)
  • 【Spring Cloud】Spring Cloud Alibaba-- 分布式事务Seata原理

    Seata 是一款开源的分布式事务解决方案,致力于提供高性能与简单易用的分布式事务服务,为用户提供了 AT、TCC、SAGA 和 XA 几种不同的事务模式: AT模式:无侵入式的分布式事务解决方案,适合不希望对业务进行改造的场景,但由于需要添加全局事务锁,对影响高并发系统的

    2024年02月08日
    浏览(78)
  • SpringCloud入门实战(十五)分布式事务框架Seata简介

    📝 学技术、更要掌握学习的方法,一起学习,让进步发生 👩🏻 作者:一只IT攻城狮 ,关注我,不迷路 。 💐学习建议:1、养成习惯,学习java的任何一个技术,都可以先去官网先看看,更准确、更专业。 💐学习建议:2、然后记住每个技术最关键的特性(通常一句话或者

    2024年02月10日
    浏览(42)
  • 【springcloud微微服务】分布式事务框架Seata使用详解

    目录 一、前言 二、事务简介 2.1 原子性 2.2 一致性 2.3 隔离性 2.4 持久性

    2023年04月26日
    浏览(42)
  • 【Spring Cloud Alibaba Seata 处理分布式事务】——每天一点小知识

                                                                                   💧 S p r i n g C l o u d A l i b a b a S e a t a 处理分布式事务 color{#FF1493}{Spring Cloud Alibaba Seata 处理分布式事务} Sp r in g Cl o u d A l ibaba S e a t a 处理分布式事务 💧

    2024年02月12日
    浏览(41)
  • 【SpringCloud】微服务保护(Sentinel)和分布式事务(Seata)

    建议学完该系列前篇 【SpringCloud】商城项目拆分微服务各个组件学习 然后再来看本文 然后学习 【RabbitMQ】交换机、队列、可靠性保证和延迟消息 在微服务远程调用的过程中,还存在几个问题需要解决。 首先是业务健壮性问题: 例如在之前的查询购物车列表业务中,购物车

    2024年01月25日
    浏览(56)
  • SpringCloud+Nacos集成Seata-1.7.0分布式事务

    Seata是一个比较成熟的分布式事务工具,非常好用,主流的的一套,网上大多都是1.4版本,以及不完整了,鄙人也是找了好久才找到有个1.7版本的详细教程(放在最后面了,毕竟是别人的技术,这里就当记录一下自己的解决方案) 首先我没去github下载相对应的seata,网址放下

    2024年02月11日
    浏览(40)
  • springcloud3 分布式事务解决方案seata之AT模式5

    1.XA模式一阶段不提交事务,锁定资源;AT模式一阶段直接提交,不锁定资源; 2.XA模式依赖数据库机制实现回滚;AT模式利用数据库快照实现数据回滚 3.XA模式强一致;AT模式最终一致。 1.2 AT模式原理 一阶段: 1.TM发起并注册全局事务到TC; 2.TM调用分支事务; 3.RM进行注册分支

    2024年02月07日
    浏览(52)
  • 分布式:一文吃透分布式事务和seata事务

    什么是事务 事务是并发控制的单位,是用户定义的一个操作序列。 事务特性 原子性(Atomicity): 事务是数据库的逻辑工作单位,事务中包括的诸操作要么全做,要么全不做。 一致性(Consistency): 事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性

    2024年02月07日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包