关于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会防止重复回查

【mq读书笔记】mq事务消息的更多相关文章

  1. 【mq读书笔记】顺序消息

    注意异常情况导致整个消费无限重试 阻塞消费 mq支持局部消息顺序消费,可以确保同一个消息消费队列中的消息被顺序消费.看下针对顺序消息在整个消费过程中做的调整: 队列负载: DefaultMQPushC ...

  2. 【mq读书笔记】定时消息

    mq不支持任意的时间京都,如果要支持,不可避免的需要在Broker层做消息排序,加上持久化方面的考量,将不可避免地带来巨大的性能消耗,所以rocketMQ只支持特定级别的延迟消息. 在Broker短通 ...

  3. 【mq读书笔记】消息队列负载与重新分配(分配 新队列pullRequest入队)

    回顾PullMessageService#run: 如果队列总没有PullRequest对象,线程将阻塞. 围绕PullRequest有2个问题: 1.PullRequest对象在什么时候创建并加入p ...

  4. 【mq读书笔记】消费进度管理

    从前2节可以看到,一次消费后消息会从ProcessQueue处理队列中移除该批消息,返回ProcessQueue最小偏移量,并存入消息进度表中.那消息进度文件存储在哪合适呢? 广播模式:同一个消费组的 ...

  5. 【mq读书笔记】消息消费队列和索引文件的更新

    ConsumeQueue,IndexFile需要及时更新,否则无法及时被消费,根据消息属性查找消息也会出现较大延迟. mq通过开启一个线程ReputMessageService来准时转发commitL ...

  6. 【mq读书笔记】消息过滤机制

    mq支持表达式过滤和类过滤两种模式,其中表达式又分为TAG和SQL92.类过滤模式允许提交一个过滤类到FilterServer,消息消费者从FilterServer拉取消息,消息经过FilterSer ...

  7. 【mq读书笔记】消息确认(失败消息,定时队列重新消费)

    接上文的集群模式,监听器返回RECONSUME_LATER,需要将将这些消息发送给Broker延迟消息.如果发送ack消息失败,将延迟5s后提交线程池进行消费. 入口:ConsumeMessageCo ...

  8. 【mq读书笔记】消息消费过程(钩子 失败重试 消费偏移记录)

    在https://www.cnblogs.com/lccsblog/p/12249265.html中,PullMessageService负责对消息队列进行消息拉取,从远端服务器拉取消息后将消息存入P ...

  9. 【mq读书笔记】消息拉取长轮训机制(Broker端)

    RocketMQ并没有真正实现推模式,而是消费者主动想消息服务器拉取消息,推模式是循环向消息服务端发送消息拉取请求. 如果消息消费者向RocketMQ发送消息拉取时,消息未到达消费队列: 如果不启用长 ...

随机推荐

  1. Yum 命令出现[Errno 256] No more mirrors to try错误的解决方式

    今天我在虚拟机上安装 NetCore 的 SDK 的时候,出现错误,执行命令:"yum install dotnet-sdk-3.1",最后安装失败,很多安装包没有找到镜像.解决方 ...

  2. CodeForces 题目乱做

    是个补题记录. 1419 除了 F 场上都过了. CF1419A Digit Game 这题好多人 FST 啊-- 考虑如果串长为奇数那么最后操作的肯定是第一个人,串长为偶数的最后操作的肯定是第二个, ...

  3. Luogu P3262 [JLOI2015]战争调度

    题意 给定一棵高度为 \(n\) 的完全二叉树,可以将节点设置成两种状态.如果某个叶子 \(x\) 的状态为 \(i\) 同时他的某个祖先也为 \(i\),那么这个叶子就会对祖先产生 \(f_{x,i ...

  4. 基于flask的python注册到eureka

    Eureka架构中的三个核心角色: 服务注册中心 Eureka的服务端应用,提供服务注册和发现功能,就是刚刚我们建立的eureka-demo 服务提供者 提供服务的应用,可以是SpringBoot应用 ...

  5. Markdown tricks

    编辑排版 仅仅了解 Markdown 语法还不够,知道这些 排版技巧 增色您的文章内容. 空格和空行 留白,从艺术角度上说,留白就是以"空白"为载体进而渲染出美的意境的艺术.从应用 ...

  6. 【Android Studio】安卓开发初体验3.1——UI设计之常用控件

    常用控件 首先对xml文件的编辑有三种模式 Code为纯代码 Split是一边代码,一边预览效果图 Designer就是有UI设计界面 TextView 用于在界面上显示一段文本信息 所有控件都可以在 ...

  7. C3P0和Druid数据库连接池

    目录 C3P0连接池 步骤: C3P0初始化: 创建C3P0工具类: 创建C3P0测试类: Druid连接池(由阿里巴巴提供的数据库连接池实现技术) 步骤: Druid初始化: 创建Druid工具类: ...

  8. Shell脚本常用命令整理

    该笔记主要整理了一些常见的脚本操作命令,大致如下(持续补充中): 1. while.for循环 1. while.for循环 #!/bin/bash # while循环 v_start_date=${ ...

  9. Spring5.0源码学习系列之浅谈循环依赖问题

    前言介绍 附录:Spring源码学习专栏 在上一章的学习中,我们对Bean的创建有了一个粗略的了解,接着本文浅谈Spring循环依赖问题,这是一个面试比较常见的问题 1.什么是循环依赖? 所谓的循环依 ...

  10. Socket 套接字的系统调用

    socket 结构 /** * struct socket - general BSD socket * @state: socket state (%SS_CONNECTED, etc) * @ty ...