关于mq食物以什么样的方式解决了什么样的问题可以参考这里:

https://www.jianshu.com/p/cc5c10221aa1

上文中示例基于mq版本较低较新的版本中TransactionListener替换掉了TransactionCheckListener,整个流程有了一些改变,但还是小事务+异步的模式 不再详述

具体的实现中:

在本地事务执行之前会先send一个prepare消息。之后执行本地事务,带着一个transactionId。

最后在endTransaction里更新事务消息的状态:

=====================

org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl#sendKernelImpl:

在消息发送之前,如果消息为prepare类型,则设置消息标准为prepare消息类型,方便消息服务期正确识别事务类型的消息。

========================

broker收到消息在sendMessageProcessor中:

如果是prepare消息执行prepareMessage方法。

事务消息存储在在未提交之前并不会存入消息原有主题,自然也不会被消费者消费。既然变更了主题,rocketmq通常会采用定时任务(单独的线程)去消费该主题,然后将该消息在满足特定条件下回复消息主题,进而被消费者消费。它与rocketmq定时消息的处理过程如出一辙。

=======================

endTransaction

Broker服务端的结束事务处理器为:EndTransactionProcessor。

如果结束事务动作为提交事务,则执行提交事务逻辑,其关键实现如下:

1.首先从结束事务请求命令中获取消息的物理偏移量(commitOffset)

2.然后回复消息的主题,消费队列,构建新的消息对象

3.然后将消息再次存储在commitlog文件中,此时的消息主题则为业务方发送的消息,将被转发到对应的消息消费队列,供消息消费者消费。

4.消息存储后,删除prepare消息,其实现方法并不是真正的删除,而是将prepare消息存储到RMQ_SYS_TRANS_OP_HALF_TOPIC主题中,表示该事务消息已经处理过,为未处理的事务回查提供查找依据。

事务回滚与提交的唯一差别是无需将消息恢复原主题,直接删除prepare消息即可。

==================

事务回查

执行完贝蒂事务返回本地事务状态为UN_KNOW时,结束事务时将不做任何处理,而是通过事务状态定时回查,以期得到发送端明确的事务操作(提交或回滚事务)

mq通过TransactionalMessageCheckService定时检查RMQ_SYS_TRANS_HALF_TOPIC中的消息,回查消息的事务状态。检测频率默认为1分钟。

重点看下其check方法:

获取RMQ_SYS_TRANS_HALF_TOPIC中的所有消息依次处理。

获取已处理消息的消息消费队列:RMQ_SYS_TRANS_OP_HALF_TOPIC。

处理已处理过的消息,这些消息不再发送事务状态回查请求。

经过一系列check之后

如果需要发送事务状态回查消息,则先将消息再次发送到RMQ_SYS_TRANS_HALF_TOPIC主题中(很奇怪不是吗)处于性能考虑。简化prepare消息队列的消息消费进度处理。后面回查的时候成功和失败进度都会前进,失败的话commitlog中的消息会再次回查,成功的话,op配合map会防止重复回查

最新文章

  1. 那些用JavaScript写的操作系统
  2. Android 第三方开源下拉框:NiceSpinner
  3. 导出excel表格
  4. PHP 错误处理
  5. 应用程序无法启动,因为应用程序的并行配置不正确,有关详细信息,请参阅应用程序事件日志,或使用命令行SxsTrace.exe工具
  6. POJ 3259 Wormholes Bellman_ford负权回路
  7. mysql时间戳的获取
  8. SimpleRpc-客户端与服务端工作模型探讨
  9. Git 分支 (二)合并
  10. Windows防火墙开启ping,禁ping的配置
  11. syncthing 多主机同步文件工具
  12. ES 6 系列 - Promise
  13. webpack 非严格模式设置 npm i babel-plugin-transform-remove-strict-mode
  14. 【AtCoder】ARC080
  15. Mac终端解压命令集合
  16. ASP.NET Core 2 学习笔记(十一)Cookies & Session
  17. Linux下安装nginx和php
  18. inode的理解
  19. ActivatedRoute 当前激活的路由对象
  20. 软工第三次作业——个人PSP

热门文章

  1. Java学习的第四十七天
  2. Python中的小括号()、中括号[]、花括号{}区别
  3. 1.使用javax.mail, spring的JavaMailSender,springboot发送邮件
  4. slam-g2o安装失败的解决问题
  5. 设置layui表格cell的内边距
  6. 搭建面向NET Framework的CI/CD持续集成环境(一)
  7. Electron入门指北
  8. .Net 5 正式版RTM 发布
  9. ixgbe 驱动 为xxx驱动做准备1
  10. 图解 Spring 循环依赖,写得太好了!