基于消息的分布式事务的概念学习
Posted FserSuN
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于消息的分布式事务的概念学习相关的知识,希望对你有一定的参考价值。
1.背景
在日常业务中存在本地事务操作和MQ共同使用的场景,可能出现任意一个失败,导致数据不一致的问题。
常见教程中一个例子:
对于订单系统来说,它创建订单的过程中实际上执行了2个步骤的操作:
1在订单库中插入一条订单数据,创建订单;
1.1 发消息给消息队列,消息的内容就是刚刚创建的订单。
1.2 发消息给消息队列,消息的内容就是刚刚创建的订单。
2 购物车系统订阅相应的主题,接收订单创建的消息,然后清理购物车,在购物车中删除订单中的商品。
上述过程可能总结为:
- 处理业务逻辑
- 发送MQ、RPC调用等非本地事务操作
1、2失败最终出现导致数据不一致的问题。
业务逻辑处理完,下一步为发送消息。如果MQ支持事务消息,那么基于事务消息,发送MQ前,数据库操作成功,随后发送MQ失败,这时就进行重试,直到成功。
业务处理完逻辑,下一步通知为RPC调用或其它非MQ的远程调用。或MQ不支持事务,那么基于本地消息表(本地消息日志)保证最终事务的执行成功。
2 事务消息机制
支持事务消息的MQ常见处理逻辑如下:
- 消息中间件支持一种中间状态的消息,例如Half状态。这种状态消息不会被消费端消费。
- 客户端先发送Half消息,成功后执行本地事务。本地事务执行成功后,提交Half消息。随后MQ服务端会把消息状态从Half转拜年为正常状态,然后投递给消费者。 在这个过程中如果本地事务执行失败,则回滚消息。服务端删除Half状态消息,不会投递给消费者。
- MQ服务端同时通过定时查询未明确状态的消息,根据本地事务的执行状态决定是提交还是回滚。
基于事务消息处理1中问题特点如下:
1.业务侧实现一个事务状态回查接口
2.发送一条消息MQ生产者和服务端需要两次远程调用。
3.适用于发送MQ同时成功的场景,RPC或者其分布式事务场景的不支持。
3. 本地消息表
2中介绍的处理以来MQ事务的支持,如果是RPC调用或MQ不支持事务消息,则可基于本地消息表的模式[1]。
系统维护一个本地消息表。这个本地消息表和业务数据表的操作同一个事务中进行。如果我们的本地业务和消息表(写消息日志)操作成功。我们在本地消息表中记录一条日志,其状态为待发送。系统通过定时任务扫描本地消息表中待发送的消息。随后执行MQ发送操作或RPC调用操作。通过一些重试策略控制,当操作调用失败,那么根据重试策略重试,直到成功。兜底情况下引入人工介入通知。防止因系统bug导致重试一致失败,方便人工排查。执行完毕后,本地消息记录将被删除。
因此基于这种模式需要在业务库中增加一张表,可能用到的字段如下:
全局事务id
全局事务名称
事务状态
事务最大重试超时时间
事务最大重试次数
下次重试执行时间
创建时间
更新时间
回调参数
4. 远程调用支持扩展
基于2、3的介绍,框架支持上,通过3的形式扩展。统一支持业务操作、MQ\\RPC\\其它调用的场景。RPC的扩展也要保证幂等。
5. ACID特性分析
基于消息的分布式事务对ACID的支持情况如下:
- 原子性:分支事务要么全部执行,要么全部取消
- 一致性:会保证最终一致性,轮训状态重试保证
- 隔离性:不支持,从概念分析可得
- 持久性:本地事务来保证持久性
基于消息的分布式事务,解偶系统。但限于最终一致性的场景使用。
6.参考
[1] 分布式事务深度分析, https://www.alibabacloud.com/blog/an-in-depth-analysis-of-distributed-transaction-solutions_597232
以上是关于基于消息的分布式事务的概念学习的主要内容,如果未能解决你的问题,请参考以下文章