分布式事务解决方案seata之AT模式原理剖析

分布式事务解决方案Seata原理剖析

稍后上传我视频分享地址:https://www.bilibili.com/video/BV11y4y1p7Ky/

默认是AT模式,我们就来剖析这AT模式到底是什么个原理

官网地址:http://seata.io/zh-cn/docs/overview/what-is-seata.html

整体机制是两阶段的提交

  • 一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
  • 二阶段:
    • 提交异步化,非常快速地完成。
    • 回滚通过一阶段的回滚日志进行反向补偿。

这是官网介绍,如果你看不懂,那么我接下来说人话,这次必懂

首先明确它的一些概念:

写隔离

  • 一阶段本地事务提交前,需要确保先拿到 全局锁
  • 拿不到 全局锁 ,不能提交本地事务。
  • 全局锁 的尝试被限制在一定范围内,超出范围将放弃,并回滚本地事务,释放本地锁。

这里的概念是十分重要的,基本上已经讲清楚了它整个运作的原理

好,接下来我来说人话

背景

官网以两个节点操作同一个数据库为例进行说明,为了更加透彻的说清楚整个原理,我来以3个节点,分别操作3个数据库为例(订单,库存,账户)

当我们进行下单的时候,会经过如下步骤

  1. 创建订单
  2. 扣减库存
  3. 扣减余额

任何一个环节出了问题,那肯定完蛋了,我想你绝对不想出现钱扣完了,但是却提醒你还未支付吧,如果出现了,我想这个平台基本上没人敢来了

按照官网写隔离的定义,整个原理的过程如下(正常流程)

  • 订单表插入一条记录
    • 先获取当前记录的本地锁,使用本地事务进行提交前尝试获取全局锁,它是第一个执行的,因此一定能获取的到全局锁,然后提交本地事务,对于提交之前的数据进行undo_log的记录,对于提交之后的数据也进行undo_log的记录
  • 库存表进行更新
    • 同样的先获取本地事务,再获取全局锁,然后提交
  • 账户表进行更新
    • 同样的先获取本地事务,再获取全局锁,然后提交

如果出现异常,如何处理?

如果更新库存表的时候出现问题,则它开始回滚,并将回滚请求发送给TC,TC收到后,根据XID与Branch ID查找TC上各个分支上的事务,并根据记录的undo_log与操作后的数据进行比较,如果相同则说明没有被修改过,则反向补偿(也就是将操作之前的数据再执行还原回去)【因为本地事务提交后,本地锁就被释放了,这期间可能被其他事务操作】,如果不一样则需要人工处理或者采取其他措施

无论是否提交或者回滚,整个执行完之后都会异步的删除undo_log记录

posted @ 2021-05-09 22:35  程序杰杰  阅读(569)  评论(0编辑  收藏  举报