分布式事务Seata中XA和AT模式介绍

1 篇文章 0 订阅

分布式事务介绍

分布式事务,就是指不是在单个服务或单个数据库架构下,产生的事务,例如:

  • 跨数据源的分布式事务
  • 跨服务的分布式事务
    在这里插入图片描述

订单的创建、库存的扣减、账户扣款在每一个服务和数据库内是一个本地事务,可以保证ACID原则。
但是当我们把三件事情看做一个"业务",要满足保证“业务”的原子性,要么所有操作全部成功,要么全部失败,不允许出现部分成功部分失败的现象,这就是分布式系统下的事务了。

分布式解决方案

  1. 解决分布式事务的方案有很多,但实现起来都比较复杂,因此我们一般会使用开源的框架来解决分布式事务问题。在众多的开源分布式事务框架中,功能最完善、使用最多的就是阿里巴巴在2019年开源的Seata了。

在这里插入图片描述

其实分布式事务产生的一个重要原因,就是参与事务的多个分支事务互相无感知,不知道彼此的执行状态。因此解决分布式事务的思想非常简单:

就是找一个统一的事务协调者TC,与多个分支事务通信,检测每个分支事务的执行状态,保证全局事务下的每一个分支事务同时成功或失败即可。大多数的分布式事务框架都是基于这个理论来实现的。

解决分布式事务的思路

分布式事务最大的问题是各个子事务的一致性问题,因此可以借鉴CAP定理和BASE理论,有两种解决思路:

  1. AP模式:各子事务分别执行和提交,允许出现结果不一致,然后采用弥补措施恢复数据即可,实现最终一致。
  2. CP模式:各个子事务执行后互相等待,同时提交,同时回滚,达成强一致。但事务等待过程中,处于弱可用状态。

但不管是哪一种模式,都需要在子系统事务之间互相通讯,协调事务状态,也就是需要一个事务协调者(TC):
在这里插入图片描述
这里的子系统事务,称为分支事务;有关联的各个分支事务在一起称为全局事务。

Seata的架构

Seata事务管理中有三个重要的角色:

  • TC (Transaction Coordinator) - **事务协调者:**维护全局和分支事务的状态,协调全局事务提交或回滚。
  • TM (Transaction Manager) - **事务管理器:**定义全局事务的范围、开始全局事务、提交或回滚全局事务。
  • RM (Resource Manager) - **资源管理器:**管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
    在这里插入图片描述
    其中,TM和RM可以理解为Seata的客户端部分,引入到参与事务的微服务依赖中即可。将来TM和RM就会协助微服务,实现本地分支事务与TC之间交互,实现事务的提交或回滚。

而TC服务则是事务协调中心,是一个独立的微服务,需要单独部署。

Seata中的XA模式

两阶段提交
XA是规范,目前主流数据库都实现了这种规范,实现的原理都是基于两阶段提交。
正常情况:
在这里插入图片描述

异常情况:在这里插入图片描述

  1. 一阶段:
  • 事务协调者通知每个事物参与者执行本地事务
  • 本地事务执行完成后报告事务执行状态给事务协调者,此时事务不提交,继续持有数据库锁
  1. 二阶段:
  • 事务协调者基于一阶段的报告来判断下一步操作
  • 如果一阶段都成功,则通知所有事务参与者,提交事务
  • 如果一阶段任意一个参与者失败,则通知所有事务参与者回滚事务

Seata的XA模型流程

Seata对原始的XA模式做了简单的封装和改造,以适应自己的事务模型,基本架构如图:
在这里插入图片描述
1. RM一阶段的工作:

  • 册分支事务到TC
  • 执行分支业务sql但不提交
  • ​报告执行状态到TC

2. TC二阶段的工作

TC检测各分支事务执行状态

  • 如果都成功,通知所有RM提交事务
  • 如果有失败,通知所有RM回滚事务

3. RM二阶段的工作:

  • 接收TC指令,提交或回滚事务

XA模式优缺点

XA模式的优点是什么?

  1. 事务的强一致性,满足ACID原则。
  2. 常用数据库都支持,实现简单,并且没有代码侵入

XA模式的缺点是什么?

  1. 因为一阶段需要锁定数据库资源,等待二阶段结束才释放,性能较差
  2. 依赖关系型数据库实现事务

实现XA模式

Seata的starter已经完成了XA模式的自动装配,实现非常简单,步骤如下:

1)修改application.yml文件(每个参与事务的微服务),开启XA模式:

seata:
  data-source-proxy-mode: XA

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

3)重启服务并测试

重启服务,再次测试,发现无论怎样,三个微服务都能成功回滚。

Seata中的AT模式

AT模式同样是分阶段提交的事务模型,不过缺弥补了XA模型中资源锁定周期过长的缺陷。

Seata的AT模型基本流程图:
在这里插入图片描述

  1. 阶段一RM的工作:
  • 注册分支事务
  • 记录undo-log(数据快照)
  • 执行业务sql并提交
  • 报告事务状态
  1. 阶段二提交时RM的工作:
  • 删除undo-log即可
  1. 阶段二回滚时RM的工作:
  • 根据undo-log恢复数据到更新前

Seata中的AT模式流程

AT模式下,当前分支事务执行流程如下:
1. 一阶段:

  • TM发起并注册全局事务到TC
  • TM调用分支事务
  • 分支事务准备执行业务SQL
  • RM拦截业务SQL,根据where条件查询原始数据,形成快照。
  • RM执行业务SQL,提交本地事务,释放数据库锁。
  • RM报告本地事务状态给TC

2. 二阶段:

  • TM通知TC事务结束
  • TC检查分支事务状态
    ​ a)如果都成功,则立即删除快照
    ​ b)如果有分支事务失败,需要回滚。

流程图:
在这里插入图片描述

实现AT模式

  1. 在分布式微服务中的数据库创建undo_log表
CREATE TABLE `undo_log` (
  `branch_id` bigint NOT NULL COMMENT 'branch transaction id',
  `xid` varchar(128) NOT NULL COMMENT 'global transaction id',
  `context` varchar(128) NOT NULL COMMENT 'undo_log context,such as serialization',
  `rollback_info` longblob NOT NULL COMMENT 'rollback info',
  `log_status` int 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 KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='AT transaction mode undo table';
  1. 然后修改application.yml文件(每个参与事务的微服务),开启AT模式:
seata:
  data-source-proxy-mode: AT

AT模式优缺点

  1. AT模式的优点:
  • 一阶段完成直接提交事务,释放数据库资源,性能比较好
  • 利用全局锁实现读写隔离
  • 没有代码侵入,框架自动完成回滚和提交
  1. AT模式的缺点:
  • 两阶段之间属于软状态,属于最终一致
  • 框架的快照功能会影响性能,但比XA模式要好很多

AT模式与XA模式的区别

简述AT模式与XA模式最大的区别是什么?

  1. XA模式一阶段不提交事务,锁定资源;AT模式一阶段直接提交,不锁定资源。
  2. XA模式依赖数据库机制实现回滚;AT模式利用数据快照实现数据回滚。
  3. XA模式强一致;AT模式最终一致
  • 15
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值