下面是这次Seata极简入门的大致讲解目录:
- 分布式事务介绍
- 两阶段提交(2pc)
- Seate简介
- Seate事务模式
- Seata实现2PC与传统2PC的区别
一.分布式事务介绍
先给大家举个例子说明下什么是分布式事务。给大家看看没有分布式事务和具有分布式事务在微服务架构中的情况。
- 没有分布式事务
假设在下面的微服务架构中,没有分布式事务,会出现什么情况?
大家可以看到,如果没有分布式事务出现异常情况,会造成两个服务之间数据不一致。库存被扣减成功了,但是订单创建失败了,或者订单创建成功了,但是库存没有扣减。
单数据源的一致性单机事务就可以完成,但是上面这种多数据源的数据一致性就需要分布式事务。 -
具有分布式事务
如果有分布式事务,上面的情况会变成什么样了?如下:
如果出现异常情况,会进行回滚操作,保证了多数据源的数据一致性。
解决方案
分布式事务用于在分布式系统中保证多节点的数据一致性。
具有多种解决方案:
- XA分布式事务协议,由Tuxedo提出
- 2PC-Two Phase Commit。两阶段提交
- 3PC-Three Phase Commit。三阶段提交、
两阶段:**准备阶段和执行阶段**
- TCC编程事务(Try-Confirm-Cancel)
TCC跟XA类似,但是需要人工手动编写代码来实现,具有代码入侵性。 - MQ消息事务
目前消息队列中,RockMQ是支持消息事务的。到达最终一致性。
二.XA协议-两阶段提交-2PC
XA协议中包含了两个角色:事务协调者和事务参与者
接下来看看两阶段提交的流程。
1.正常流程
- 第一阶段(正常)
第一阶段也就是准备阶段;
1. 事务协调者会向所有事务参与者发送准备(Prepare)请求;
2. 每个事务参与者收到请求,会处理本地事务相关的数据更新操作,并写入到undo_log表中,并告诉事务协调者“我完成了”;
- 第二阶段(正常)
事务协调者收到所有参与者的请求后,整个分布式事务就会进入到第二阶段,也就是执行阶段
1. 事务协调者收到所有参与者都是正向返回,则会向所有参与者发出commit请求;
2. 参与者收到commit请求后,就会提交本地事务,并释放锁资源;完成之后告诉事务协调者“我完成了”;
3. 事务协调者收到所有参与者的“我完成了”,然后就会结束分布式事务;
2. 异常处理流程
-
第一阶段(异常)
1. 事务协调者会向所有事务参与者发送准备(Prepare)请求;
2. 如果事务参与者B出现失败情况,则会告诉协调者“我失败了”;
-
第二阶段(异常)
当事务协调者收到所有参与者返回的消息,分布式事务进入第二阶段;
1. 事务协调者收到某个参与者是失败的情况,则会向所有参与者发送Rollback请求;
2. 参与者收到Rollback请求时,会根据undo_log表回滚本地事务,并释放锁资源;
3.存在的缺点
咱们总结下传统的2pc流程的相关缺点:
-
同步阻塞问题
执行过程中,所有的参与节点都是事务阻塞型。当参与者访问公共资源时,其他第三方节点访问公共资源不得不等待,处于阻塞状态; -
单点故障
由于协调者的重要性,一旦协调者发生故障,则参与者就会一直处于阻塞状态。特别是在第二阶段,如果协调者出现故障,则所有的参与者都还处于锁定事务资源的状态,而无法继续完成事务操作; -
数据不一致
如果在第二阶段,协调者发送Commit请求后发生故障,可能会导致一部分参与者执行了commit请求,一部分没有执行,会造成数据不一致的情况;
针对上面这些缺点,提出了三阶段(3PC)提交;
三阶段提交有两个改动点,下面简单列举下:
- 同时在事务协调者和参与者中都引人了超时机制;
- 在第一阶段和第二阶段中间新增了一个准备阶段(CanCommit),保证了在最后提交之前所有参与者状态一致;
三.Seata 简介
1. Seata的由来
- 2019年1月,阿里巴巴中间件团队发起了开源项目Fascar;
- Fascar开源之后,蚂蚁金服加入了Fascar社区进行共建;
- 为了打造更中立,更开放,生态更加丰富的分布式事务开源社区,大家决定对Fascar进行品牌升级,更名为Seata(Simple Extensible Autonomous Transcation Architecture);是一套一站式分布式事务解决方案;
2. Seata是什么?
来自官网的介绍:
Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务。Seata将为用户提供AT,TCC,SAGA和XA事务协议。为用户打造一站式分布式解决方案。
3. Seata术语
- 事务协调者-TC(Transaction Coordinator)
维护全局和分支事务状态,驱动全局事务提交或者回滚; - 事务管理器-TM(Transaction Manager)
定义全局事务的范围,开始全局事务,提交或者回滚全局事务; - 资源管理器-RM(Resource Manager)
管理分支事务处理的资源,并驱动分支事务提交或者回滚;
从图中可以看出TC是单独部署的服务端,TM和RM是嵌入到应用中的Client客户端;
四.Seata 事务模式
1.Seata 全局事务架构
定义:全局事务可以理解为若干分支事务的协调;
Seata的全局事务可以理解为两个阶段:
- 执行阶段
执行分支事务,并保证执行结果是可回滚的和可持久化的; - 完成阶段
根据执行阶段结果形成的决议,应用通过TM发出的全局提交或回滚请求给TC,TC命令TM驱动分支事务进行Commit或者Rollback;
从Seata官网获取的一个整体架构图:
1. TM负责向TC发起(Begin),提交(Commit),回滚(Rollback)全局事务;
2. TM把代表全局事务的XID绑定到分支事务上;
3. RM注册到TC,还会把分支事务执行结果反馈给TC;
4. TC发送分支提交Commit或者分支回滚Rollback给RM;
2.Seata 事务模式
定义: Seata事务模式也叫做分支事务模式,是指运行在Seata全局事务框架下的分支事务的行为模式;
目前Seata提供了四种事务模式:
- AT模式
- TCC模式
- SAGA模式
- XA模式
不同的模式区别在于【分支事务】使用【不同的方式】完成全局事务的两个阶段
从图中可以看到AT和XA是业务无侵入的,TCC和SAGA是有业务侵入的;
下面咱们看看AT模式和TCC模式,目前应用的比较多的两种;
3. AT模式
- 前提
基于支持本地ACID事务的关系型数据库;
Java应用,通过JDBC访问数据库; - 整体机制
两阶段提交协议的演变;
一阶段:业务数据和undo_log日志记录在同一个本地事务中提交,释放本地锁和连接资源;
二阶段:提交异步化;回滚通过一阶段undo_log回滚日志进行反向补偿; -
流程图
1. 第一阶段
注册分支事务到TC;
通过代理数据源DataSourceProxy对业务sql进行解析,并转换成undolog;并与业务sql在一个事务内入库;
提交本地事务,上报状态给TC;
2. 第二阶段
分布式事务操作成功,则TC通知RM异步删除undolog;
分布式事务操作失败,
TM向TC发布回滚请求;
RM收到协调器TC发来回滚指令,通过XID和BranchID找到对应回滚日志;
通过回滚日志生成反向的补偿SQl并执行,完成分支事务的回滚;
-
UNDO_LOG 表
生成的undolog表数据如下:
数据中存储了操作前镜像,操作后镜像,有全局事务XID,和分支事务BranchID等信息;
4. TCC模式
对AT模式有些了解后,咱们再看看TCC模式;
TCC模式介绍
TCC--Try,Confirm,Cancel;业务方需要实现这三个方法来完成分布式事务;
TCC模式是指把自定义分支事务纳入到全局事务进行管理;-
TCC模式优缺点
- 业务代码侵入严重
每个阶段的数据处理都需要自己编写代码来实现,事务框架无法自动处理; - 效率高
不必对数据加全局锁;
- 业务代码侵入严重
-
TCC模式流程
1. 第一阶段
TM开启全局事务;
执行TCC参与者的Try方法时,被TCC拦截器拦截,在Try方法执行前注册分支事务到TC;在Try方法执行后向TC报告分支事务的状态;
2. 第二阶段
TM通知TC执行提交事务,如果出现异常,则会通知TC执行回滚事务;
TC收到TM提交或回滚的通知,则会遍历各个分支事务,逐个进行提交或回滚;
5.AT/TCC模式适用场景
对于上述两种模式进行了简单的介绍,咱们来列举下适用的场景
对比项 | AT模式 | TCC模式 |
---|---|---|
集成难度 | 低 | 高 |
数据库改造 | UNDO_LOG表 | 业务表增加状态和锁定的字段 |
实现机制 | DataSource代理 | 自定义TCC方法实现 |
适用场景 | 遗留老的项目 自研所有场景项目 需要快速构建分布式事务 |
新项目 高性能要求项目 复杂场景项目 金融支付场景 |
五. Seata实现2PC与传统2PC区别
- 层次架构方面
传统2PC方案的RM实际上是在数据库层,RM本质就是数据库本身,通过XA协议实现;
而Seata的RM是以Jar包的形式作为中间件部署在应用程序中的; - 两阶段提交方面
传统2PC无论第二阶段决议是提交还是回滚,事务资源的锁都需要保持到第二阶段才能释放;
而Seata在第一阶段将本地事务提交,从而省去了第二阶段持锁时间,整体提高了效率;
相关参考文章:
Seata官网
Seata服务端搭建
Seata客服端集成(springcloud+nacos+seata)
欢迎大家留言,提出建议,感谢!