首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >消息中间件(三):Rocketmq如何支持分布式事务消息

消息中间件(三):Rocketmq如何支持分布式事务消息

作者头像
程序员小明
发布2019-06-03 17:58:03
2.1K0
发布2019-06-03 17:58:03
举报
文章被收录于专栏:程序员小明程序员小明

场景

A(存在DB操作)、B(存在DB操作)两方需要保证分布式事务一致性,通过引入中间层MQ,A和MQ保持事务一致性(异常情况下通过MQ反查A接口实现check),B和MQ保证事务一致(通过重试),从而达到最终事务一致性。 原理

大事务 = 小事务 + 异步

MQ与DB一致性原理(两方事务)

流程图

流程图 上图是RocketMQ提供的保证MQ消息、DB事务一致性的方案。 MQ消息、DB操作一致性方案:

  • 发送消息到MQ服务器,此时消息状态为SEND_OK。此消息为consumer不可见。
  • 执行DB操作;DB执行成功Commit DB操作,DB执行失败Rollback DB操作。
  • 如果DB执行成功,回复MQ服务器,将状态为COMMIT_MESSAGE;如果DB执行失败,回复MQ服务器,将状态改为ROLLBACK_MESSAGE。注意此过程有可能失败。
  • MQ内部提供一个名为“事务状态服务”的服务,此服务会检查事务消息的状态,如果发现消息未COMMIT,则通过Producer启动时注册的TransactionCheckListener来回调业务系统,业务系统在checkLocalTransactionState方法中检查DB事务状态,如果成功,则回复COMMIT_MESSAGE,否则回复ROLLBACK_MESSAGE。 说明: 上面以DB为例,其实此处可以是任何业务或者数据源。 以上SEND_OK、COMMIT_MESSAGE、ROLLBACK_MESSAGE均是client jar提供的状态,在MQ服务器内部是一个数字。

TransactionCheckListener 是在消息的commit或者rollback消息丢失的情况下才会回调(上图中灰色部分)。这种消息丢失只存在于断网或者rocketmq集群挂了的情况下。当rocketmq集群挂了,如果采用异步刷盘,存在1s内数据丢失风险,异步刷盘场景下保障事务没有意义。所以如果要核心业务用Rocketmq解决分布式事务问题,建议选择同步刷盘模式。

多系统之间数据一致性(多方事务)

多方事务

当需要保证多方(超过2方)的分布式一致性,上面的两方事务一致性(通过Rocketmq的事务性消息解决)已经无法支持。这个时候需要引入TCC模式思想(Try-Confirm-Cancel,不清楚的自行百度)。 以上图交易系统为例:

  • 交易系统创建订单(往DB插入一条记录),同时发送订单创建消息。通过RocketMq事务性消息保证一致性
  • 接着执行完成订单所需的同步核心RPC服务(非核心的系统通过监听MQ消息自行处理,处理结果不会影响交易状态)。执行成功更改订单状态,同时发送MQ消息。
  • 交易系统接受自己发送的订单创建消息,通过定时调度系统创建延时回滚任务(或者使用RocketMq的重试功能,设置第二次发送时间为定时任务的延迟创建时间。在非消息堵塞的情况下,消息第一次到达延迟为1ms左右,这时可能RPC还未执行完,订单状态还未设置为完成,第二次消费时间可以指定)。延迟任务先通过查询订单状态判断订单是否完成,完成则不创建回滚任务,否则创建。 PS:多个RPC可以创建一个回滚任务,通过一个消费组接受一次消息就可以;也可以通过创建多个消费组,一个消息消费多次,每次消费创建一个RPC的回滚任务。 回滚任务失败,通过MQ的重发来重试。 以上是交易系统和其他系统之间保持最终一致性的解决方案。

案例分析

单机环境下的事务示意图

如下为A给B转账的例子。

步骤

动作

1

锁定B的账户

2

锁定B的账户

3

检查A账户是否有1元

4

A的账户扣减1元

5

给B的账户加1元

6

解锁B的账户

7

解锁A的账户

以上过程在代码层面甚至可以简化到在一个事物中执行两条sql语句。

分布式环境下事务

和单机事务不同,A、B账户可能不在同一个DB中,此时无法像在单机情况下使用事物来实现。此时可以通过一下方式实现,将转账操作分成两个操作。

  • A账户

步骤

动作

1

锁定A的账户

2

检查A账户是否有1元

3

A的账户扣减1元

4

解锁A的账户

  • MQ消息

A账户数据发生变化时,发送MQ消息,MQ服务器将消息推送给转账系统,转账系统来给B账号加钱。

  • B账户

步骤

动作

1

锁定B的账户

2

给B的账户加1元

3

解锁B的账户

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员小明 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MQ与DB一致性原理(两方事务)
  • 多系统之间数据一致性(多方事务)
    • 案例分析
      • 单机环境下的事务示意图
      • 分布式环境下事务
相关产品与服务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档