分布式事务
1. 概念
分布式事务:
- 在分布式系统下,一个业务横跨了多个服务,每个服务都是一个分支事务,要保证所有分支事务的最终一致性,这样的事务就是分布式事务
分布式事务指事务的参与者位于不同的分布式系统的不同节点之上。也就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上。
微服务中,一个业务操作通常要跨多个数据库、服务才能完成。例如电商行业中比较常见的下单付款案例,包括下面几个行为:
- 创建新订单
- 扣除金额
- 扣减商品库存
当我们把三件事情看做一个"业务",要满足保证“业务”的原子性,要么所有操作全部成功,要么全部失败,不允许出现部分成功部分失败的现象。
2. 基础理论
2-1. CAP定理
- Consistency(一致性):某个节点修改了一个数据,那么之后其他所有节点读取这条数据的时候,得到的一定是最新的数据。
- Availability(可用性):用户访问某个节点时,总能返回响应数据(允许不是最新的数据,或者是表示失败的信息)。
- Partition tolerance (分区容错性):在分布式系统中,当由于网络问题导致出现分区的时候,仍然能够对外提供服务。
分区:分布式系统中,多个节点之前的网络本来是连通的,但是因为某些故障(比如部分节点网络出了问题)某些节点之间不连通了,整个网络就分成了几块区域,这就叫网络分区。
CAP定理指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。
作为一个分布式系统来讲:P是必须要保证的,那么剩下的A和C就只能满足一个
- 如果此时要保证一致性C,就必须等待网络恢复,完成数据同步后,整个集群才对外提供服务,那么此时服务处于阻塞状态,不可用。
- 如果此时要保证可用性A,就需要马上返回结果,那此时各节点未完成数据同步,则返回的数据就不一致。
- Zookeeper 是CP架构,Eureka 是AP架构,Nacos 不仅支持 CP 架构也支持 AP 架构。
2-2. BASE理论
BASE理论本质上是对CAP的延伸和补充,是对CAP中的AP方案的一个补充,即在选择AP方案的情况下,如何更好地最终达到C。
- Basically Available (基本可用):分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。
- Soft State(软状态):在一定时间内,允许出现中间状态,比如临时的不一致状态。
- Eventually Consistent(最终一致性):虽然无法保证强一致性,但是在软状态结束后,最终达到数据一致。
2-3. 理论应用
分布式事务最大的问题是各个子事务的一致性问题,因此可以借鉴CAP定理和BASE理论,有两种解决思路:
- AP模式:各子事务分别执行和提交,允许出现结果不一致,然后采用弥补措施恢复数据即可,实现最终一致。
- CP模式:各个子事务执行后互相等待,同时提交,同时回滚,达成强一致,但事务等待过程中,处于弱可用状态。
2-4. 解决方案
两阶段提交
整个事务分成两个阶段:
- 阶段一: 准备阶段,事务协调者会询问所有的参与者是否准备就绪,并等待他们的响应。
- 阶段二: 提交阶段,协调者根据所有参与者的响应,通知所有参与者,执行提交或者回滚。
正常情况:
异常情况:
TCC事务
TCC即为Try Confirm Cancel,它属于补偿型分布式事务。TCC实现分布式事务一共有三个步骤:
- Try:做业务检查(一致性)及资源预留(隔离),此阶段仅是一个初步操作,它和后续的Confirm 一起才能真正构成一个完整的业务逻辑
- Confirm:做确认提交,Try阶段所有分支事务执行成功后开始执行Confirm
- Cancel:在业务执行错误需要回滚的状态下执行分支事务的业务取消,预留资源释放
举例,一个扣减用户余额的业务。假设账户A原来余额是100,需要余额扣减30元。
阶段一( Try ):检查余额是否充足,如果充足则冻结金额增加30元,可用余额扣除30
此时,总金额 = 冻结金额 + 可用金额,数量依然是100不变。事务直接提交无需等待其它事务。
阶段二(Confirm):假如要提交(Confirm),则冻结金额扣减30
确认可以提交,不过之前可用金额已经扣减过了,这里只要清除冻结金额就好了
阶段三(Canncel):如果要回滚(Cancel),则冻结金额扣减30,可用余额增加30
需要回滚,那么就要释放冻结金额,恢复可用金额
通常情况下,采用TCC则认为Confirm和Cancel阶是一定成功的。若真的出错了,需引入重试机制或人工处理。
3. 分布式事务框架Seata
Seata主要由三个重要组件组成:
- TC:Transaction Coordinator 事务协调器,管理全局的事务的状态,用于全局性事务的提交和回滚。
- TM:Transaction Manager 事务管理器,用于开启、提交或者回滚全局事务。
- RM:Resource Manager 资源管理器,用于分支事务上的资源管理,向TC注册分支事务,上报分支事务的状态,接受TC的命令来提交或者回滚分支事务。
Seata基于上述架构提供了四种不同的分布式事务解决方案:
- XA模式:强一致性分阶段事务模式,牺牲了一定的可用性,无业务侵入
- AT模式:最终一致的分阶段事务模式,无业务侵入,也是Seata的默认模式
- TCC模式:最终一致的分阶段事务模式,有业务侵入
- SAGA模式:长事务模式,有业务侵入
3-1. XA模式
XA 规范 是 X/Open 组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准。
目前主流数据库都实现了这种规范,实现的原理都是基于两阶段提交。
Seata的XA模式对原始的两阶段提交做了简单的封装和改造,以适应自己的事务模型,基本架构如图:
一阶段:
① 注册分支事务到TC ② 执行分支业务sql但不提交 ③ 报告执行状态到TC
二阶段:
TC检测各分支事务执行状态,如果都成功,通知所有RM提交事务;如果有失败,通知所有RM回滚事务
RM接收TC指令,提交或回滚事务
优缺点:
- 优点
- 事务的强一致性,满足ACID原则。
- 常用数据库都支持,实现简单,并且没有代码侵入
- 缺点
- 因为一阶段需要锁定数据库资源,等待二阶段结束才释放,性能较差
- 依赖关系型数据库实现事务,非关系型数据库无法实现
3-2. AT模式
AT模式同样是分阶段提交的事务模型,不过缺弥补了XA模型中资源锁定周期过长的缺陷。
阶段一RM的工作:① 注册分支事务 ② 记录undo-log(数据快照) ③ 执行业务sql并提交 ④ 报告事务状态
阶段二RM的工作:如果要回滚,需要根据日志恢复数据到更新前,然后删除日志; 如果要执行提交,直接删除日志即可
AT与XA的区别
- XA模式一阶段不提交事务,锁定资源;AT模式一阶段直接提交,不锁定资源。
- XA模式依赖数据库机制实现回滚;AT模式利用数据快照实现数据回滚。
- XA模式强一致;AT模式最终一致
3-3. TCC模式
Seata中的TCC模型依然延续之前的事务架构,如图:
优缺点
优点
- 一阶段完成直接提交事务,释放数据库资源,性能好
- 相比AT模型,无需生成快照,无需使用全局锁,性能最强
- 不依赖数据库事务,而是依赖补偿操作,可以用于非事务型数据库
缺点
- 有代码侵入,需要人为编写try、Confirm和Cancel接口,太麻烦
- 软状态,事务是最终一致
- 需要考虑Confirm和Cancel的失败情况,做好幂等处理