微服务实战 06 分布式事务常见解决方案
参考《Spring Cloud Alibaba 微服务原理与实战》
上一篇介绍了分布式事务入门,这边文章来一起了解一下分布式事务的常见解决方案
微服务实战 05 分布式事务 入门
TCC
TCC ( Try - Confirm - Cancel ) 他把完成的业务差分为如下三个步骤
- Try:这个阶段主要对数据的校验或者资源的预留
- Confirm:确认真正执行的任务,只操作Try阶段预留的资源
- Cancel:取消执行,释放Try阶段预留的资源
其实 TCC 就是两阶段提交的思想
- 第一阶段:通过 try进行准备工作
- 第二阶段: Confirm/Cancel 表示Try阶段的操作的提交和回滚
在一些特殊情况下,比如图中的 业务服务2 宕机或者出现异常,导致该服务并没有收到TCC事务协调器的Cancel或者Confirm请求,TCC事务框架会记录一些分布式事务的操作日志,保证分布式事务运行的各个阶段和状态.TCC服务支持接口调用失败发起充实,以达到数据的最终一致性。也正因如此,TCC暴漏的接口都需要满足幂等性
基于可靠性消息的最终一致性方案
基于可靠性消息的最终一致性方案是互联网公司比较常用的分布式数据一致性解决方案。
它主要利用消息中间件的可靠性机制来实现数据一致性投递。
支付服务收到支付结果通知后,先更新订单状态,再发送消息到消息队列,账户服务监听指定队列的消息并进行响应的处理,完成数据的同步。
在第四和第五步骤中,支付服务需要 操作订单数据库,发送消息到消息队列,在这里存在操作的原子性问题,要么两个操作都成功,要么都失败
- 先发送消息,在执行数据库操作,消息发送成功但是数据库操作失败,导致数据不一致
- 先执行事务操作,在发送消息,MQ响应超时导致异常,从而将本地事务回滚,但是消息可能已经发送成功了,也会存在数据一致性问题。
如果使用 RacketMQ ,可以使用他的事务模型
如果使用 RabbitMq 也可以使用事务机制但是影响性能
也可使使用下面方案先执行数据库事务操作,再发送消息
每天一个知识点- rabbitMq 如何防止消息不丢失
最大努力通知型
最大努力通知型也是基于可靠性消息的最终一致性方案的方案类型,它是一种简单柔性事务解决方案,适用于对数据一致性要求不高的场景。
在下图中的第四步,如果 支付服务没有返回支付宝 “success” 状态码,那么这个支付结果回调请求会以衰减重试机制(即逐步拉大间隔时间进行通知)知道达到最大通知次数,如果达到最大次数后支付服务还没有返回确认,这种情况下,支付宝提供查询支付结果接口,根据返回结果支付服务可以更新订单状态。
支付宝网页端支付时序图