本文讲述阿里云官方文档中关于通过MQ实现分布式事务最终一致性原理

概念介绍

  • 事务消息:消息队列 MQ 提供类似 X/Open XA 的分布式事务功能,通过消息队列 MQ 事务消息能达到分布式事务的最终一致。

  • 半事务消息:暂不能投递的消息,发送方已经成功地将消息发送到了消息队列 MQ 服务端,但是服务端未收到生产者对该消息的二次确认,此时该消息被标记成“暂不能投递”状态,处于该种状态下的消息即半事务消息。

  • 消息回查:由于网络闪断、生产者应用重启等原因,导致某条事务消息的二次确认丢失,消息队列 MQ 服务端通过扫描发现某条消息长期处于“半事务消息”时,需要主动向消息生产者询问该消息的最终状态(Commit 或是 Rollback),该询问过程即消息回查。

适用场景

事务消息的适用场景示例:

通过购物车进行下单的流程中,用户入口在购物车系统,交易下单入口在交易系统,两个系统之间的数据需要保持最终一致,这时可以通过事务消息进行处理。交易系统下单之后,发送一条交易下单的消息到消息队列 MQ,购物车系统订阅消息队列 MQ 的交易下单消息,做相应的业务处理,更新购物车数据。

交互流程

事务消息交互流程如下图所示。

事务消息发送步骤如下:

  1. 发送方将半事务消息发送至消息队列 MQ 服务端。

  2. 消息队列 MQ 服务端将消息持久化成功之后,向发送方返回 Ack 确认消息已经发送成功,此时消息为半事务消息。

  3. 发送方开始执行本地事务逻辑。

  4. 发送方根据本地事务执行结果向服务端提交二次确认(Commit 或是 Rollback),服务端收到 Commit 状态则将半事务消息标记为可投递,订阅方最终将收到该消息;服务端收到 Rollback 状态则删除半事务消息,订阅方将不会接受该消息。

事务消息回查步骤如下:

  1. 在断网或者是应用重启的特殊情况下,上述步骤 4 提交的二次确认最终未到达服务端,经过固定时间后服务端将对该消息发起消息回查。

  2. 发送方收到消息回查后,需要检查对应消息的本地事务执行的最终结果。

  3. 发送方根据检查得到的本地事务的最终状态再次提交二次确认,服务端仍按照步骤 4 对半事务消息进行操作。

注意事项

  1. 事务消息的 Group ID 不能与其他类型消息的 Group ID 共用。与其他类型的消息不同,事务消息有回查机制,回查时消息队列 MQ 服务端会根据 Group ID 去查询客户端。

  2. 通过 ONSFactory.createTransactionProducer 创建事务消息的 Producer 时必须指定 LocalTransactionChecker 的实现类,处理异常情况下事务消息的回查。

  3. 事务消息发送完成本地事务后,可在 execute 方法中返回以下三种状态:

    • TransactionStatus.CommitTransaction:提交事务,允许订阅方消费该消息。

    • TransactionStatus.RollbackTransaction:回滚事务,消息将被丢弃不允许消费。

    • TransactionStatus.Unknow:暂时无法判断状态,等待固定时间以后消息队列 MQ 服务端向发送方进行消息回查。

  4. 可通过以下方式给每条消息设定第一次消息回查的最快时间:

     
    1. Message message = new Message();
    2. // 在消息属性中添加第一次消息回查的最快时间,单位秒。例如,以下设置实际第一次回查时间为 120 秒 ~ 125 秒之间
    3. message.putUserProperties(PropertyKeyConst.CheckImmunityTimeInSeconds,"120");
    4. // 以上方式只确定事务消息的第一次回查的最快时间,实际回查时间向后浮动 0 秒 ~ 5 秒;如第一次回查后事务仍未提交,后续每隔 5 秒回查一次

MQ关于实现最终一致性分布式事务原理解析的更多相关文章

  1. LCN解决分布式事务原理解析+项目实战(原创精华版)

    写在前面: 原创不易,如果觉得不错推荐一下,谢谢! 由于工作需要,公司的微服务项目需解决分布式事务的问题,且由我进行分布式事务框架搭建和整合工作. 那么借此机会好好的将解决分布式事务的内容进行整理一下 ...

  2. 分布式事务(3)---RocketMQ实现分布式事务原理

    分布式事务(3)-RocketMQ实现分布式事务原理 之前讲过有关分布式事务2PC.3PC.TCC的理论知识,博客地址: 1.分布式事务(1)---2PC和3PC原理 2.分布式事务(2)---TCC ...

  3. 解决分布式事务基本思想Base和CPA理论、最终一致性|刚性事务、柔性事务

    在学习解决分布式事务基本思路之前,大家要熟悉一些基本解决分布式事务概念名词比如:CAP与Base理论.柔性事务与刚性事务.理解最终一致性思想,JTA+XA.两阶段与三阶段提交等. 如何保证强一致性呢? ...

  4. JAVA分布式事务原理及应用(转)

      JTA(Java Transaction API)允许应用程序执行分布式事务处理--在两个或多个网络计算机资源上访问并且更新数据. JDBC驱动程序的JTA支持极大地增强了数据访问能力. 本文的目 ...

  5. JAVA分布式事务原理及应用

    JTA(Java Transaction API)允许应用程序执行分布式事务处理--在两个或多个网络计算机资源上访问并且更新数据.JDBC驱动程序的JTA支持极大地增强了数据访问能力. 本文的目的是要 ...

  6. [java][db]JAVA分布式事务原理及应用

    JTA(Java Transaction API)同意应用程序运行分布式事务处理--在两个或多个网络计算机资源上訪问而且更新数据.JDBC驱动程序的JTA支持极大地增强了数据訪问能力.  本文的目的是 ...

  7. 分布式架构原理解析,Java开发必修课

    1. 分布式术语 1.1. 异常 服务器宕机 内存错误.服务器停电等都会导致服务器宕机,此时节点无法正常工作,称为不可用. 服务器宕机会导致节点失去所有内存信息,因此需要将内存信息保存到持久化介质上. ...

  8. tcc分布式事务框架解析

    前言碎语 楼主之前推荐过2pc的分布式事务框架LCN.今天来详细聊聊TCC事务协议. 2pc实现:https://github.com/codingapi/tx-lcn tcc实现:https://g ...

  9. 终于有人把“TCC分布式事务”实现原理讲明白了!

    之前网上看到很多写分布式事务的文章,不过大多都是将分布式事务各种技术方案简单介绍一下.很多朋友看了还是不知道分布式事务到底怎么回事,在项目里到底如何使用. 所以这篇文章,就用大白话+手工绘图,并结合一 ...

随机推荐

  1. day6(celery配置与基本使用)

    1.celery配置与基本使用 1.1 安装celery pip install celery @ https://github.com/celery/celery/tarball/master 1. ...

  2. python3 通过 pybind11 使用Eigen加速代码

    python是很容易上手的编程语言,但是有些时候使用python编写的程序并不能保证其运行速度(例如:while 和 for),这个时候我们就需要借助c++等为我们的代码提速.下面是我使用pybind ...

  3. PyQt(Python+Qt)学习随笔:QListView的spacing属性

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QListView的spacing属性用于控制视图布局中数据项周围填充的空白空间的大小.缺省值为0, ...

  4. Win10激活失败并提示错误代码0xC004C003的解决方法

    亲测,可用. 步骤如下: 进入cmd,管理员权限登录 slmgr.vbs /upk slmgr /ipk W269N-WFGWX-YVC9B-4J6C9-T83GX slmgr /skms zh.us ...

  5. 第三篇 Scrum 冲刺博客

    一.站立式会议 1. 会议照片 2. 工作汇报 团队成员名称 昨日(24日)完成的工作 今天(25日)计划完成的工作 工作中遇到的困难 陈锐基 - 个人信息编辑后与组件关联- 表白墙数据用 Vuex  ...

  6. 百度前端技术学院-基础-day2

    2020.9.15 今天是学习前端基础技术的第二天,今天制作了一个在线简历,纯html的那种.帮助我复习了以前的基础知识,也增加了新的知识点,比如制作列表可以用fieldset来整合数据. 我的在线简 ...

  7. css外边距重叠及避免方法

    <html lang="en"> <head> <meta charset="UTF-8"> <meta name=& ...

  8. linux 上安装部署python

    一般在linux中使用python 需要安装pyenv 进行版本控制 因为linux6.9自带的Python是2.6的 同时很多命令都是基于2.6开发的 所以系统环境不能改 我们要开发 只能用pyen ...

  9. MVCAdmin项目知识点记录

    1.在过滤器中,用ViewBag类似的东西,要((ViewResult)filterContext.Result).ViewBag. 2.Controller中自己定义的非Action方法中(包括构造 ...

  10. 除了MD5加密,试一下签名吧

    需求 MD5加密,简单密码用彩虹表很容易破解. 密码不能被暴力破解,可以根据定制字符,时间戳等防止破解 解决方案 签名 密码加密 源码 const crypto = require('crypto') ...