分布式事务
文章目录
- 分布式事务
场景:下单操作需要依赖订单服务和库存服务,这两个服务部署在两个不同的节点,就必须牵涉到分布式事务
一,本地消息表
本地消息表与业务数据表处于同一个数据库中,这样就能利用本地事务来保证在对这两个表的操作满足事务特性,并且使用消息队列来保证最终一致性
缺陷:
- 本地消息表和业务耦合在一起,不可独立伸缩
- 本地消息表是基于数据库来做的,数据库要读写磁盘IO的,因此会有性能瓶颈
二,2PC 两阶段提交
两阶段提交,通过引入协调者来协调参与者的行为,并最终决定这些参与者是否要真正执行事务
准备阶段
协调者询问每一个参与者事务是否执行成功(事务执行但是未提交),参与者发回事务执行结果,在这一阶段处理事务commit
操作,其他事情都做完了
提交/回滚阶段
如果事务在每个参与者上都执行成功,协调者会让每个参与者提交事务,否则,协调者会让参与者回滚事务
整体流程:
如果在准备阶段有一个参与者返回失败,那么写协调者会向所有参与者发送回滚事务的请求
如果在第二阶段执行失败,协调者也是让所有参与者回滚事务,如果回滚失败则不断重试
优点:
- 两阶段提交是一种强一致性设计,保证了数据的强一致性
缺陷:
- 同步阻塞
- 所有事务参与者在等待其他参与者响应的时候都处于同步阻塞的状态,无法进行其他操作
- 单点问题
- 事务协调者是核心角色,如果发生故障,特别是在提交阶段发生故障,那么事务参与者就会一直阻塞,无法完成其他操作
- 数据不一致
- 在提交阶段,如果协调者只发送了
commit
消息,此时网络发生异常,那么只有部分参与者接收到commit
消息,也就是说只有部分参与者提交了事务,剩下的参与者没有收到commit
消息,会一直阻塞,使得数据不一致
- 过于保守
- 任意一个事务参与者失败就会导致整个事务失败
三,3PC 三段式提交
3PC相比于2PC,引入超时时间解决了同步阻塞问题和2PC的协调者单点缺陷
3PC流程:
- 准备阶段:资源检查,看能否执行事务,实际上只是检查,不会执行任何事务操作,只有收到所有参与者的可以执行响应才能继续下一步,只要有一个失败就执行事务中断
- 预提交阶段:
- 执行事务操作,但是并不提交事务
- 提交阶段:
- 正在提交事务
相比于2PC,多了一个资源检查操作,而不是一上来就直接锁定资源,减少了同步阻塞的概率,检查阶段发现不能执行事务则直接中断事务
四,TCC
TCC就是
Try
-> Confirm
-> Cancel
三个操作的简称
Try阶段:
- 资源预留/锁定
Confirm阶段:
- 确认执行业务逻辑操作
Cancel阶段:
- 取消执行业务逻辑
- 解决了协调者单点,由主业务方发起并完成这个业务活动。业务活动管理器也变成多点,引入集群。
- 同步阻塞:引入超时,超时后进行补偿,并且不会锁定整个资源,将资源转换为业务逻辑形式,粒度变小。
- 数据一致性,有了补偿机制之后,由业务活动管理器控制一致性
在 Try 阶段,是对业务系统进行检查及资源预览,比如订单和存储操作,需要检查库存剩余数量是否够用,并进行预留,预留操作的话就是新建一个可用库存数量字段,Try 阶段操作是对这个可用库存数量进行操作。
基于 TCC 实现分布式事务,会将原来只需要一个接口就可以实现的逻辑拆分为 Try、Confirm、Cancel 三个接口,所以代码实现复杂度相对较高