基于本地消息表的分布式事务解决方案总结
什么是分布式事务
- 一个应用系统操作两个数据库(两个不同的主节点上), 要使数据强一致性, 此时就不能用传统的事务来解决强一致性, 此时需要用到分布式事务
- CAP原则
- C consistency(一致性), A (availability)可用性 P(paratiton tolerance)区分容错性。 CAP原则指CAP三者不能同时满足,要么能同时满足AP 要么同时满足CP(P 是分布式的基础, 不能实现P就谈不上分布式系统了)
基于本地消息表常用的分布式事务解决方案
场景
- 用户支付完成后,会调用 会计服务生成会计凭证到数据库中,此时若支付服务处理完,直接调用会计服务会遇到分布式事务的问题(如果此时发生网络抖动, 导致支付成功写入库中,但是生成会计凭证失败)
进阶一
- 用户完成支付后,此时需要立刻给用户一个支付成功反馈。为了提高响应速度和解耦,因此可以引入 mq 来做异步生成会计凭证, 用户完成支付后 可以将消息投递到 mq 中,然后会计服务再去监听 mq 消息去处理消费逻辑 :
进阶二
-
此时又引入了新的问题 大概列举如下:
- 支付成功后,往 mq 中投递消息,突然网络抖动,投递失败了怎么办
- mq 接收消息后,由于内部原因,消息丢失怎么办
- 会计服务在接收到消息,还没有来得及处理,由于网络抖动,消息丢失了怎么办?
-
此时可以引入本地消息表结合 mq 来解决上面出现的问题,保证消息的可靠性, 大致流程如下
- 在支付库中加入一张消息表来记录支付消息,即用户支付成功后同时往这张消息表插入一条支付成功的消息, 状态为
发送中
, 注意: 写入消息表裹入支付事务中, 要成功 ,都成功 - 往 mq pay_msg队列中写入消息,写入的消息要跟本地消息表中的数据一致
- 会计服务监听到这条消息了,此时会计服务开始生成会计凭证
- 会计凭证生成后,再反向向mq投递一条消费成功的消息到back_msg队列中
- 支付服务又来监听这个会计服务消费成功的消息,当支付服务监听到这个消费成功的消息后,此时再将本地消息表的消息状态改为
已发送
- 如果以上的步骤有一步失败, 此时还需要一个定时任务,定时扫描本地消息表中状态为
发送中
的消息投递到 mq 中的 pay_msg 队列中。 整个系统就算是完成了
- 在支付库中加入一张消息表来记录支付消息,即用户支付成功后同时往这张消息表插入一条支付成功的消息, 状态为