事务的主动方需要额外新建事务消息表,用于记录分布式事务的消息的发生、处理状态 。
整个业务处理流程如下:
文章插图
步骤1 事务主动方处理本地事务 。 事务主动发在本地事务中处理业务更新操作和写消息表操作 。上面例子中库存服务阶段再本地事务中完成扣减库存和写消息表(图中1、2) 。
步骤2 事务主动方通过消息中间件,通知事务被动方处理事务通知事务待消息 。消息中间件可以基于Kafka、RocketMQ消息队列,事务主动方法主动写消息到消息队列,事务消费方消费并处理消息队列中的消息 。上面例子中,库存服务把事务待处理消息写到消息中间件,订单服务消费消息中间件的消息,完成新增订单(图中3 - 5) 。
【一文彻底弄懂分布式事务里的最终一致性】步骤3 事务被动方通过消息中间件,通知事务主动方事务已处理的消息 。 上面例子中,订单服务把事务已处理消息写到消息中间件,库存服务消费中间件的消息,并将事务消息的状态更新为已完成(图中6 - 8)
为了数据的一致性,当处理错误需要重试,事务发送方和事务接收方相关业务处理需要支持幂等 。具体保存一致性的容错处理如下:
- 1、当步骤1处理出错,事务回滚,相当于什么都没发生 。
- 2、当步骤2、步骤3处理出错,由于未处理的事务消息还是保存在事务发送方,事务发送方可以定时轮询为超时消息数据,再次发送的消息中间件进行处理 。事务被动方消费事务消息重试处理 。
- 3、如果是业务上的失败,事务被动方可以发消息给事务主动方进行回滚 。
- 4、如果多个事务被动方已经消费消息,事务主动方需要回滚事务时需要通知事务被动方回滚 。
- 从应用设计开发的角度实现了消息数据的可靠性,消息数据的可靠性不依赖于消息中间件,弱化了对MQ中间件特性的依赖 。
- 方案轻量,容易实现 。
- 与具体的业务场景绑定,耦合性强,不可公用 。
- 消息数据与业务数据同库,占用业务系统资源 。
- 业务系统在使用关系型数据库的情况下,消息服务性能会受到关系型数据库并发性能的局限 。
- 服务A提交数据
- 向消息中心发送消息
- 消息中心向订阅方推送消息
- 订阅方处理自己的业务逻辑
- 失败去反复去重试,直到成功,而不是向强一致性那样,把A回滚的
推荐阅读
- 这一次,彻底弄懂“秒杀系统”
- 一文带你了解 JavaScript 函数式编程
- 一文看懂开源监控神器--prometheus部署教程,值得收藏
- 一文搞定Java热更新
- 世界艾滋病日:“携手抗艾,重在预防”让世界彻底无“艾”
- 一文看懂mysql数据库备份恢复
- 集合 一文了解 JavaScript 中的 Set
- 一文读懂银行数据架构体系
- 并使用java实现 一文彻底看懂Base64编码解码原理
- 一文了解网络交换机的6种命令配置模式