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

参见
还是比较清晰的。简单的说 就是在你业务逻辑过程中,需要发送一条消息给订阅消息的人,但是期望是 此逻辑过程完全成功完成之后才能使订阅者收到消息。
业务逻辑过程 假设是这样的:
逻辑部分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. Rest_framework之版本控制、响应器和分页器

    一.访问频率补充 频率: 自定义: 1 定义一个类MyThrottles allow_request(频率限制的逻辑) ==>这两个函数都是派生出来的,继承的类里面封装的. wait(返回一个数 ...

  2. 将一个字符与对应Ascii码互转

    package nicetime.com.practies; /** * Java中将一个字符与对应Ascii码互转 1 byte = 8bit 可以表示 0-127 */public class G ...

  3. android app 压力测试工具-monkey tool

    一.什么是Monkey? Monkey测试是Android自动化测试的一种手段,Monkey测试本身非常简单,就是模拟用户的按键输入,触摸屏输入,手势输入等,看设备多长时间会出异常. Monkey是A ...

  4. Android商城开发系列(二)——App启动欢迎页面制作

    商城APP一般都会在应用启动时有一个欢迎界面,下面我们来实现一个最简单的欢迎页开发:就是打开商城App,先出现欢迎界面,停留几秒钟,自动进入应用程序的主界面. 首先先定义WelcomeActivity ...

  5. ABAP Development Tools的语法高亮实现原理

    ABAP Development Tools的前端是Java,根本识别不了ABAP.那么在ADT里的ABAP语法高亮是如何实现的? 第一次打开一个report时,显示在ADT里的代码是没有任何语法高亮 ...

  6. 让您的Eclipse具有千变万化的外观

    大家每天用Eclipse做Java开发,是否厌倦了Eclipse千篇一律的白色背景呢? 看看Jerry这几种不同风格的Eclipse外观,是不是有耳目一新的感觉?如何做到的? 需要给Eclipse安装 ...

  7. SAP公有云和私有云解决方案概述

    SAP公有云解决方案见下图最右侧,比较著名的有SAP SuccessFactors和SAP Cloud for Customer(C4C)等,作为SAP软件即服务(SaaS)的解决方案. 而最左侧的S ...

  8. Java 守护线程(Daemon) 例子

    当我们在Java中创建一个线程,缺省状态下它是一个User线程,如果该线程运行,JVM不会终结该程序.当一个线被标记为守护线程,JVM不会等待其结束,只要所有用户(User)线程都结束,JVM将终结程 ...

  9. [VC]WindowProc和DefWindowProc函数

    在Windows操作系统里,当窗口显示之后,它就可以接收到系统源源不断地发过来的消息,然后窗口就需要处理这些消息,因此就需要一个函数来处理这些消 息.在API里定义了一个函数为回调函数,当系统需要向窗 ...

  10. [论文理解] Rapid-Object-Detection-using-a-Boosted-cascade-of-simple-features

    Rapid-Object-Detection-using-a-Boosted-cascade-of-simple-features 简介 文章是2001年发表的,是一篇很经典的Object Detec ...