为什么消息要具备事务能力

参见
还是比较清晰的。简单的说 就是在你业务逻辑过程中,需要发送一条消息给订阅消息的人,但是期望是 此逻辑过程完全成功完成之后才能使订阅者收到消息。
业务逻辑过程 假设是这样的:
逻辑部分a-->发消息给MQ-->逻辑部分b
假设我们在发送消息给MQ之后执行逻辑部分b时产生了异常,那如果MQ不具备事务消息能力时,订阅者也收到了消息。这是我们不希望见到的。

分布式事务基础概念

  1. 关于分布式事务、两阶段提交协议、三阶提交协议
  2. 理解分布式事务的两阶段提交2pc
  3. 分布式事务(一)两阶段提交及JTA
  4. 分布式系统常用思想和技术总结
  5. 【整理】脑裂问题
  6. 分布式系统的事务处理
  7. 多版本并发控制(MVCC)在分布式系统中的应用
  8. 戏说PAXOS
  9. 阿里云消息队列 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-事务消息实现原理的更多相关文章

  1. rocketmq源码分析2-broker的消息接收

    broker消息接收,假设接收的是一个普通消息(即没有事务),此处分析也只分析master上动作逻辑,不涉及ha. 1. 如何找到消息接收处理入口 可以通过broker的监听端口10911顺藤摸瓜式的 ...

  2. RocketMQ源码分析之从官方示例窥探:RocketMQ事务消息实现基本思想

    摘要: RocketMQ源码分析之从官方示例窥探RocketMQ事务消息实现基本思想. 在阅读本文前,若您对RocketMQ技术感兴趣,请加入RocketMQ技术交流群 RocketMQ4.3.0版本 ...

  3. RocketMQ 源码分析 —— Message 发送与接收

    1.概述 Producer 发送消息.主要是同步发送消息源码,涉及到 异步/Oneway发送消息,事务消息会跳过. Broker 接收消息.(存储消息在<RocketMQ 源码分析 —— Mes ...

  4. 【RocketMQ源码分析】深入消息存储(3)

    前文回顾 CommitLog篇 --[RocketMQ源码分析]深入消息存储(1) ConsumeQueue篇 --[RocketMQ源码分析]深入消息存储(2) 前面两篇已经说过了消息如何存储到Co ...

  5. 【RocketMQ源码分析】深入消息存储(2)

    前文回顾 CommitLog篇 --[RocketMQ源码分析]深入消息存储(1) MappedFile篇 --[RocketMQ源码分析]深入消息存储(3) 前文说完了一条消息如何被持久化到本地磁盘 ...

  6. redis源码分析之事务Transaction(下)

    接着上一篇,这篇文章分析一下redis事务操作中multi,exec,discard三个核心命令. 原文地址:http://www.jianshu.com/p/e22615586595 看本篇文章前需 ...

  7. 并发编程学习笔记(9)----AQS的共享模式源码分析及CountDownLatch使用及原理

    1. AQS共享模式 前面已经说过了AQS的原理及独享模式的源码分析,今天就来学习共享模式下的AQS的几个接口的源码. 首先还是从顶级接口acquireShared()方法入手: public fin ...

  8. Guava 源码分析之Cache的实现原理

    Guava 源码分析之Cache的实现原理 前言 Google 出的 Guava 是 Java 核心增强的库,应用非常广泛. 我平时用的也挺频繁,这次就借助日常使用的 Cache 组件来看看 Goog ...

  9. 从SpringBoot源码分析 配置文件的加载原理和优先级

    本文从SpringBoot源码分析 配置文件的加载原理和配置文件的优先级     跟入源码之前,先提一个问题:   SpringBoot 既可以加载指定目录下的配置文件获取配置项,也可以通过启动参数( ...

随机推荐

  1. 洛谷P2430 严酷的训练

    第一眼看这道题...啊哈,啥??? 仔细看一看,发现:诶, 这不是01背包吗? 两人水平值的比值*老王做题用时 可以算出WKY做每道题的用时. 那么每道题的p就可以转换成费用c[i], 价值q就是w[ ...

  2. CF1157D N Problems During K Days

    思路: 在1, 2, 3, ... , k的基础上贪心构造. 实现: #include <bits/stdc++.h> using namespace std; typedef long ...

  3. cocos的Director、Scence、Layer(一)---摘自于官方文档

    基本结构图(重要) Director: 有那些作用? OpenGL ES的初始化,场景的转换,游戏暂停继续的控制,世界坐标和GL坐标之间的切换,对节点(游戏元素)的控制,游戏数据的保存调用,屏幕尺寸的 ...

  4. 【深度精讲】JFinal中的Ret和Kv工具类的区别,你用对了吗?

    在JFinal中有两个类Map的工具类,一个是有状态的Ret,一个是无状态的Kv,各种自己的应用场景,你用对了吗? 下面我们从多个方面来探究一下,JFinal针对这两个类的设计: 一.位置-com.j ...

  5. Image(支持 XML 序列化),注意C#中原生的Image类是无法进行Xml序列化的

    /// <summary> /// Image(支持 XML 序列化) /// </summary> [XmlRoot("XmlImage")] publi ...

  6. NullPointerException检测

    APET-NPE插件工作原理 android应用程序编译的过程如下: 从图中,我们可以看出,app编译大致经历了四大阶段:java source files -> .class files -& ...

  7. 2017.10.2 QBXT 模拟赛

    题目链接 T1 我们所要求得是(a*b)|x 也就是 使(a*b)的倍数小于x的个数之和 1<=x<=n 我们可以 找一个c使得 (a*b*c)<=x 由于我们所求的是一个三元有序对 ...

  8. [CV笔记]inRange对图像进行分割

    先把图像转为hsv空间,然后对图像进行inrange取到hsv范围内的图像,我这里要做的是取到图中的几个白色区域以及里面的手写数字,方法可能不是最好的,因为刚入门cv没几天,先试着用所学取到这几个区域 ...

  9. javaweb基础(14)_jsp的原理

    一.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写h ...

  10. Python Web 架构

    1. Django(全能型)2. Tornado3. BottlePython+Bottle+Sina SAE快速构建网站http://www.cnblogs.com/Xjng/p/3511983.h ...