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 既可以加载指定目录下的配置文件获取配置项,也可以通过启动参数( ...
随机推荐
- Spring 设计原则
Spring 框架有四大原则(Spring所有的功能和设计和实现都基于四大原则): 1. 使用POJO进行轻量级和最小侵入式开发. 2. 通过依赖注入和基本接口编程实现松耦合. 3. 通过AOP和基于 ...
- Generator 和 函数异步应用 笔记
Generator > ES6 提供的一种异步编程解决方案 > Generator 函数是一个状态机,封装了多个内部状态.还是一个遍历器对象生成函数.返回<label>遍历器对 ...
- Ubuntu11.04 安装cuda4.3
一.卸载官方驱动并安装显卡驱动 1. sudo gedit /etc/modprobe.d/blacklist.conf,在文件末尾加上如下五行,然后保存 blacklist vga16fb blac ...
- 关于SQL Server索引密度的知识
文章主要描述的是SQL Server索引密度(Index Densities),当一个查询的SARG 的值直到查询运行时才得以知晓,或是SARG是一个关于索引的多列时,SQL Server才使用为索引 ...
- BeautifulSoup库测试代码
import requests from bs4 import BeautifulSoup import time headers={ #'User-Agent':'Nokia6600/1.0 (3. ...
- NHibernate使用之详细图解
本文档适合初级开发者或者是第一次接触NHibernate框架的朋友,其中NHibernate不是最新的版本,但是一个比较经典的版本 NHibernate 2.1.2,其中用红线标注的部分一定要仔细看, ...
- 字符编码:Unicode和UTF-8的关系
今天中午,我突然想搞清楚Unicode和UTF-8之间的关系,于是就开始在网上查资料. 结果,这个问题比我想象的复杂,从午饭后一直看到晚上9点,才算初步搞清楚. 下面就是我的笔记,主要用来整理自己的思 ...
- ssh整合思想初步 structs2 Spring Hibernate三大框架各自要点
Web层用Structs2的action Service层用Spring的IoC和aop以及JdbcTemplate或者Transaction事务(创建对象及维护对象间的关系) Dao层用Hibern ...
- sqlite3 数据库使用
首先,通过官网下载sqlite3.h和sqlite3.c两个文件,用于调用里面的api函数操作数据库. 这里也提供链接地址下载:http://pan.baidu.com/s/1qWzjqPY 其中里面 ...
- 初涉网络流[EK&dinic]
主要还是板子 Edmonds-Karp 从S开始bfs,直到找到一条到达T的路径后将该路径增广,并重复这一过程. 在处理过程中,为了应对“找到的一条路径把其他路径堵塞”的情况,采用了建反向弧的方式来实 ...