怅然|消息队列之事务消息,RocketMQ 和 Kafka是如何做的?( 二 )
然后如果都try成功了那么就执行confirm方法 , 大家都来做真正的业务操作 , 如果有一个try失败了那么大家都执行cancel操作 , 来撤回刚才的修改 。
可以看到TCC其实对业务的耦合性很大 , 因为业务上需要做一定的改造才能完成这三个方法 , 这其实就是TCC的缺点 , 并且confirm和cancel操作要注意幂等 , 因为到执行这两步的时候没有退路 , 是务必要完成的 , 因此需要有重试机制 , 所以需要保证方法幂等 。
事务消息事务消息就是今天文章的主角了 , 它主要是适用于异步更新的场景 , 并且对数据实时性要求不高的地方 。
它的目的是为了解决消息生产者与消息消费者的数据一致性问题 。
比如你点外卖 , 我们先选了炸鸡加入购物车 , 又选了瓶可乐 , 然后下单 , 付完款这个流程就结束了 。
而购物车里面的数据就很适合用消息通知异步删除 , 因为一般而言我们下完单不会再去点开这个店家的菜单 , 而且就算点开了购物车里还有这些菜品也没有关系 , 影响不大 。
我们希望的就是下单成功之后购物车的菜品最终会被删除 , 所以要点就是下单和发消息这两个步骤要么都成功要么都失败 。
RocketMQ 事务消息我们先来看一下 RocketMQ 是如何实现事务消息的 。
RocketMQ 的事务消息也可以被认为是一个两阶段提交 , 简单的说就是在事务开始的时候会先发送一个半消息给 Broker。
半消息的意思就是这个消息此时对 Consumer 是不可见的 , 而且也不是存在真正要发送的队列中 , 而是一个特殊队列 。
发送完半消息之后再执行本地事务 , 再根据本地事务的执行结果来决定是向 Broker发送提交消息 , 还是发送回滚消息 。
此时有人说这一步发送提交或者回滚消息失败了怎么办?
影响不大 , Broker 会定时的向 Producer 来反查这个事务是否成功 , 具体的就是 Producer 需要暴露一个接口 , 通过这个接口 Broker 可以得知事务到底有没有执行成功 , 没成功就返回未知 , 因为有可能事务还在执行 , 会进行多次查询 。
如果成功那么就将半消息恢复到正常要发送的队列中 , 这样消费者就可以消费这条消息了 。
我们再来简单的看下如何使用 , 我根据官网示例代码简化了下 。
可以看到使用起来还是很简便直观的 , 无非就是多加个反查事务结果的方法 , 然后把本地事务执行的过程写在 TransationListener 里面 。
至此 RocketMQ 事务消息大致的流程已经清晰了 , 我们画一张整体的流程图来过一遍 , 其实到第四步这个消息要么就是正常的消息 , 要么就是抛弃什么都不存在 , 此时这个事务消息已经结束它的生命周期了 。
RocketMQ 事务消息源码分析然后我们再从源码的角度来看看到底是怎么做的 , 首先我们看下sendMessageInTransaction方法 , 方法有点长 , 不过没有关系结构还是很清晰的 。
推荐阅读
- 湖人队|狂轰62+21+13!浓眉太无解,詹姆斯后仰杀死比赛,湖人却获坏消息!
- 智通财经|| 远洋服务向港交所递表 在管面积约4230万平方米,新股消息
- 第一财经|免税概念利好消息频出,机构看好板块未来强劲增长丨牛熊眼
- 第一财经|新力控股联席董事长陈凯传出离职消息
- 带你逛服贸 | 文化服务专题展 规模大、颜值高、创意多
- 山东鲁能|山东鲁能迎来好消息,“大鱼”正积极运作,李霄鹏乐坏了
- 财经|新力控股联席董事长陈凯传出离职消息
- 半年|新力控股联席董事长陈凯传出离职消息
- 中国军备|外媒大胆预测,今年下半年中国将迎来三个好消息,每个都举世瞩目
- 华光环能|好消息!华光环能:子公司中标污水处理总承包项目
