分布式事务,及其解决方案之一——本地消息表

转自:https://mp.weixin.qq.com/s/zp1kJ895zBb9vA7fgJ20eQ

仅做个人备份,浏览请看原文

目录

分布式事务

本地消息表

其他解决方案详见:https://mp.weixin.qq.com/s/zp1kJ895zBb9vA7fgJ20eQ 


分布式事务

聊什么是分布式事务前,先聊一下我们熟悉的单机事务。所谓单机事务是相对分布式事务来说的,即数据库事务。大家都知道数据库事务有ACID这四个特性:

A(Atomicity):指单个事务中的操作要不都执行,要不都不执行

C(Consistency):指事务前后数据的完整性必须保持一致

I(Isolation):指多个事务对数据可见性的规则

D(Durability):指事务提交后,就会被永久存储下来

既然数据库事务有这四个特性的,那么分布式事务也不例外,应该具备这四个特性。

在微服务架构下,服务之间通过RPC远程调用,相对单机事务来说,多了“网络通信”这一不确定因素,使得本来服务的调用只有“成功”和“失败”这两种返回结果,变为“成功”、“失败”和“未知”三种返回结果。系统之间的通信可靠性从单一系统中的可靠变成了微服务架构之间的不可靠,分布式事务其实就是在不可靠的通信下实现事务的特性。一般因为网络导致的异常可能有机器宕机、网络异常、消息丢失、消息乱序、数据错误、不可靠的TCP、存储数据丢失、其他异常等等。

本地消息表

本地消息表方案应该是业界内使用最为广泛的,因为它使用简单,成本比较低。本地消息表的方案最初是由eBay提出(完整方案),核心思路是将分布式事务拆分成本地事务进行处理。

它的处理流程如下:

  • 事务发起方把要处理的业务事务和写消息表这两个操作放在同一个本地事务里

  • 事务发起方有一个定时任务轮询消息表,把没处理的消息发送到消息中间件

  • 事务被动方从消息中间件获取消息后,返回成功

  • 事务发起方更新消息状态为已成功

图片

从处理流程来看,本地消息表方案是一个基于消息中间件的可靠性来达到事务的最终一致性的方案。

一些分析:

  • 把业务处理和写消息表放在同一个事务是为了失败/异常后可以同时回滚

  • 为什么不直接发消息,而是先写消息表?试想,如果发送消息超时了,即不确定消息中间件收到消息没,那么你是重试还是抛异常回滚事务呢?回滚是不行的,因为可能消息中间件已经收到消息,接收方收到消息后做处理,导致双方数据不一致了;重试也是不行的,因为有可能会一直重试失败,导致事务阻塞。

  • 基于上述分析,消息的接收方是需要做幂等操作的

本地消息表方案整体来说还是比较简单、可用的,但是也有以下缺点

  • 消息数据和业务数据耦合,消息表需要根据具体的业务场景制定,不能公用。就算可以公用消息表,对于分库的业务来说每个库都是需要消息表的。

  • 只适用于最终一致的业务场景。例如在 A -> B场景下,在不考虑网络异常、宕机等非业务异常的情况下,A成功的话,B肯定也会成功的。

其他解决方案详见:https://mp.weixin.qq.com/s/zp1kJ895zBb9vA7fgJ20eQ 

猜你喜欢

转载自blog.csdn.net/chushoufengli/article/details/115235347