rocketmq源码分析4-事务消息实现原理
为什么消息要具备事务能力
参见
还是比较清晰的。简单的说 就是在你业务逻辑过程中,需要发送一条消息给订阅消息的人,但是期望是 此逻辑过程完全成功完成之后才能使订阅者收到消息。
业务逻辑过程 假设是这样的:
逻辑部分a-->发消息给MQ-->逻辑部分b
假设我们在发送消息给MQ之后执行逻辑部分b时产生了异常,那如果MQ不具备事务消息能力时,订阅者也收到了消息。这是我们不希望见到的。
分布式事务基础概念
- 关于分布式事务、两阶段提交协议、三阶提交协议
- 理解分布式事务的两阶段提交2pc
- 分布式事务(一)两阶段提交及JTA
- 分布式系统常用思想和技术总结
- 【整理】脑裂问题
- 分布式系统的事务处理
- 多版本并发控制(MVCC)在分布式系统中的应用
- 戏说PAXOS
- 阿里云消息队列 MQ关于事务消息的文档
rocketmq具备事务能力的demo
参见TransactionProducerDemo.java
向producer注册的TransactionCheckListener实现并没有用,因为返回LocalTransactionState.UNKNOW状态时,在3.2.6版本中,是不支持此状态下回调TransactionCheckListener的,具体参见以下两个issue。
事务消息 LocalTransactionState.UNKNOW 状态下不回查 #221
开源版本支持事务消息吗 #364
测试过程中发现返回UNKNOW状态是不能正确达到期望的,但是返回ROLLBACK_MESSAGE状态还是能达到期望的。
实现分析入口
这个实现的入口还是比较容易找的,只要搜寻ROLLBACK_MESSAGE这个变量的引用即可发现。顺着搜索查看,其实很容易发现,客户端在收到业务逻辑返回的事务状态时会发送一条结束事务的指令给broker。
// com.alibaba.rocketmq.client.impl.MQClientAPIImpl.endTransactionOneway(String, EndTransactionRequestHeader, String, long) 871行
RemotingCommand request =
RemotingCommand.createRequestCommand(RequestCode.END_TRANSACTION, requestHeader);
按broker对外部指令的常规做法,一般会有一个Processor与之对应。是EndTransactionProcessor,看BrokerController374行其注册的地方,没错。
EndTransactionProcessor分析(broker侧)
如果LocalTransactionExecuter.executeLocalTransactionBranch返回LocalTransactionState.ROLLBACK_MESSAGE时,EndTransactionProcessor会清空message的body的置成null,queueOffset也不会更新,那么consumer就收不到消息了。
//--EndTransactionProcessor.processRequest 200行--
if (MessageSysFlag.TransactionRollbackType == requestHeader.getCommitOrRollback()) {
msgInner.setBody(null);
}
如果LocalTransactionExecuter.executeLocalTransactionBranch返回LocalTransactionState.COMMIT_MESSAGE,那么EndTransactionProcessor则会照常put message。
事务消息分为两个阶段,prepare阶段与commit阶段。prepare阶段的消息会写入store,只是写完之后的queueOffset(逻辑位置)为0(commit阶段写完消息后的queueOffset就不是0了。);
// -- com.alibaba.rocketmq.store.CommitLog.DefaultAppendMessageCallback.doAppend(long, ByteBuffer, int, Object) 1002行 --
final int tranType = MessageSysFlag.getTransactionValue(msgInner.getSysFlag());
switch (tranType) {
// Prepared and Rollback message is not consumed, will not enter the
// consumer queue
case MessageSysFlag.TransactionPreparedType:
case MessageSysFlag.TransactionRollbackType:
queueOffset = 0L;
break;
case MessageSysFlag.TransactionNotType:
case MessageSysFlag.TransactionCommitType:
default:
break;
待分析问题列表:
1. prepare阶段已经将消息发了过去,commit的时候是否还会再发送一次消息?
2. rollback的时候是否会将prepare的消息删除?
rocketmq源码分析4-事务消息实现原理的更多相关文章
- rocketmq源码分析2-broker的消息接收
broker消息接收,假设接收的是一个普通消息(即没有事务),此处分析也只分析master上动作逻辑,不涉及ha. 1. 如何找到消息接收处理入口 可以通过broker的监听端口10911顺藤摸瓜式的 ...
- RocketMQ源码分析之从官方示例窥探:RocketMQ事务消息实现基本思想
摘要: RocketMQ源码分析之从官方示例窥探RocketMQ事务消息实现基本思想. 在阅读本文前,若您对RocketMQ技术感兴趣,请加入RocketMQ技术交流群 RocketMQ4.3.0版本 ...
- RocketMQ 源码分析 —— Message 发送与接收
1.概述 Producer 发送消息.主要是同步发送消息源码,涉及到 异步/Oneway发送消息,事务消息会跳过. Broker 接收消息.(存储消息在<RocketMQ 源码分析 —— Mes ...
- 【RocketMQ源码分析】深入消息存储(3)
前文回顾 CommitLog篇 --[RocketMQ源码分析]深入消息存储(1) ConsumeQueue篇 --[RocketMQ源码分析]深入消息存储(2) 前面两篇已经说过了消息如何存储到Co ...
- 【RocketMQ源码分析】深入消息存储(2)
前文回顾 CommitLog篇 --[RocketMQ源码分析]深入消息存储(1) MappedFile篇 --[RocketMQ源码分析]深入消息存储(3) 前文说完了一条消息如何被持久化到本地磁盘 ...
- redis源码分析之事务Transaction(下)
接着上一篇,这篇文章分析一下redis事务操作中multi,exec,discard三个核心命令. 原文地址:http://www.jianshu.com/p/e22615586595 看本篇文章前需 ...
- 并发编程学习笔记(9)----AQS的共享模式源码分析及CountDownLatch使用及原理
1. AQS共享模式 前面已经说过了AQS的原理及独享模式的源码分析,今天就来学习共享模式下的AQS的几个接口的源码. 首先还是从顶级接口acquireShared()方法入手: public fin ...
- Guava 源码分析之Cache的实现原理
Guava 源码分析之Cache的实现原理 前言 Google 出的 Guava 是 Java 核心增强的库,应用非常广泛. 我平时用的也挺频繁,这次就借助日常使用的 Cache 组件来看看 Goog ...
- 从SpringBoot源码分析 配置文件的加载原理和优先级
本文从SpringBoot源码分析 配置文件的加载原理和配置文件的优先级 跟入源码之前,先提一个问题: SpringBoot 既可以加载指定目录下的配置文件获取配置项,也可以通过启动参数( ...
随机推荐
- 零基础逆向工程13_C语言07_指针01_反汇编
1."带*类型"的特征探测 宽度 在同一个平台下,任何指针变量的尺寸都是一样的(都等于系统字长),如在32位平台中任何类型指针宽度都是32位. 声明 1.带有* 的变量类型的标准写 ...
- 多线程串口通信 MFC CSerialPort
写在前面: 晚上应该继续完成未写完的代码,但Chrome上打开的标签实在太多了,约30个了,必须关掉一些,所以需要把自己看的整理一下然后关掉.本次主要写点MFC环境下多线程串口通信相关的东西,这包括线 ...
- 编写C#程序,自动将bing首页图片设为壁纸
任务目标: 1,获取图片 2,设为壁纸 3,自动化 环境需求: .NET Framework 4.0+, Visual Studio 2017 ==================== 1,获取图片 ...
- UVA1602 Lattice Animals 网格动物 (暴力,STL)
多联骨牌的生成办法,维基上只找到固定的骨牌fix,而free的没有找到. 于是只好写个set判重的简单枚举了. 旋转的操作,可以在坐标轴上画个点,以原点为轴心,逆时针旋转90度,新的点的坐标为(-y, ...
- Android(java)学习笔记108:Android的Junit调试
1. Android的Junit调试: 编写android应用的时候,往往我们需要编写一些业务逻辑实现类,但是我们可能不能明确这个业务逻辑是否可以成功实现,特别是逻辑代码体十分巨大的时候,我们不可能一 ...
- js原型,原型链的理解
1.所有引用类型(函数.数组.对象)都拥有_proto_属性(隐式原型) 2.所有函数拥有prototype属性(显式原型)(仅限函数) 3.原型对象:拥有prototype属性的对象,在定义函数时就 ...
- HTML5中的Web Workers
https://www.cnblogs.com/yanan-boke/p/6954390.html https://segmentfault.com/a/1190000014938305 HTML5 ...
- stixel world论文总结
1.The Stixel World - A Compact Medium Level Representation of the 3D-World:http://pdfs.semanticschol ...
- a survey for RL
• A finite set of states St summarizing the information the agent senses from the environment at eve ...
- PAT (Basic Level) Practise (中文)- 1018. 锤子剪刀布 (20)
http://www.patest.cn/contests/pat-b-practise/1018 大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示: 现给出两人的交锋记录,请统 ...