分布式事务的八种方案解析(1)

2024-06-15 10:20

本文主要是介绍分布式事务的八种方案解析(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

针对不同的分布式场景业界常见的解决方案有2PC、TCC、可靠消息最终一致性、最大努力通知等方案,以下总结8 种常见的解决方案,帮助大家在实际的分布式系统中更好地运用事务。

1.2PC

二阶段提交协议(Two-phase commit protocol),简称 2PC。2PC是将整个事务流程分为两个阶段:

● 1.准备阶段(Prepare phase)

● 2.提交阶段(commitphase)

2是指两个阶段,P是指准备阶段,C是指提交阶段

在计算机中部分关系数据库如Oracle、MySQL支持两阶段提交协议,如下图:

● 准备阶段(Prepare phase):事务管理器给每个参与者发送Prepare消息,每个数据库参与者在本地执行事务,并写本地的Undo/Redo日志,此时事务没有提交。(Undo日志是记录修改前的数据,用于数据库回滚,Redo日志是记录修改后的数据,用于提交事务后写入据文件)

● 提交阶段(commit phase):如果事务管理器收到了参与者的执行失败或者超时消息时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据事务管理器的指令执行提交或者回滚操作,并释放事务处理过程中使用的锁资源。

注意:必须在最后阶段释放锁资源

下图展示了2PC的两个阶段,分成功和失败两个情况说明:

成功情况:

异常情况:

2PC优缺点:

优点

● 简单直观:逻辑清晰,易于理解和实现。

● 原子性保证:能够保证跨多个分布式节点的事务的原子性。

缺点:

● 同步阻塞:因为一阶段需要锁定数据库资源,等待二阶段结束才释放,性能较差,在高并发场景下不适用

● 单点故障问题,如果协调者在第二阶段崩溃,参与者可能会无限期地等待指令,因为它们不知道应该提交还是回滚。这使得整个系统容易受到单点故障的影响

● 数据不一致问题,如果在第二阶段中协调者向某些参与者发送了提交指令,而其他参与者因为网络问题没有收到指令,那么这些没有收到指令的参与者可能会选择回滚,导致数据不一致

2.3PC

3PC,即Three-Phase Commit,是一种分布式事务协议,用于在分布式系统中确保多个参与者之间的事务操作的一致性和可靠性。它是在两阶段提交(2PC)协议的基础上发展而来,解决了2PC协议可能出现的悬挂事务问题。

3PC协议将提交操作分为三个阶段,分别是准备阶段、提交准备阶段和提交阶段,每个阶段都有对应的操作和协议。

准备阶段(CanCommit):

● 协调者:向所有参与者发送CanCommit准备请求,询问它们是否可以提交事务。

● 参与者:执行本地事务,检查是否能够执行,如果可以执行则返回可以提交,否则返回不可以提交。

提交准备阶段(PreCommit):

● 协调者: 根据参与者的反馈情况决定是否进行提交准备

○ 如果所有参与者都返回“可以提交”,协调者向所有参与者发送提交请求,告知它们可以进行提交准备。

○ 如果有任何参与者返回“不可以提交”或者超时未响应,则协调者向所有参与者发送中止请求,取消事务。

提交阶段(DoCommit/DoAbort):

● 如果协调者 接收到所有参与者的确认提交消息,则向所有参与者发送最终的提交请求,提交事务。

● 如果协调者接收到任何参与者的中止请求,或者在提交准备阶段超时未收到所有参与者的响应,则向所有参与者发送中止请求,取消事务

3PC协议相对于2PC协议的改进在于增加了一个准备阶段,使得参与者在准备阶段就能够知道是否可以提交事务,从而避免了悬挂事务问题。然而,3PC协议仍然存在着协调者单点故障、消息丢失等问题,因此在实际应用中并不常见,一般更多地使用2PC、Saga等分布式事务解决方案

3.TCC

TCC是Try、Confirm、Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作:预处理Try、确认Confirm、撤销Cancel。Try操作业务检查及资源预留,Confirm做业务确认操作,Cancel实现一个与Try相反的操作即回滚操作。TM首先发起所有的分支事务的try操作,任何一个分支事务的try操作执行失败,TM将会发起所有分支事务的Cancel操作,若try操作全部成功,TM将会发起所有分支事务的Confirm操作,其中Confirm/Cancel操作若执行失败,TM会进行重试。

● 分支事务成功情况:

● image分支事务失败的情况:

imageTCC分为三个阶段

● Try 阶段:是做业务检查(一致性)及资源预留(隔离),此阶段仅是一个初步操作,它和后续的Confirm 一起才能真正构成一个完整的业务逻辑。

● Confirm 阶段:是做确认提交,Try阶段所有分支事务执行成功后开始执行 Confirm。通常情况下,采用TCC则认为 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。若Confirm阶段真的出错了,需引入重试机制或人工处理。。

● Cancel 阶段:是在业务执行错误需要回滚的状态下执行分支事务的业务取消,预留资源释放。通常情况下,采用TCC则认为Cancel阶段也是一定成功的。若Cancel阶段真的出错了,需引入重试机制或人工处理

TCC需要注意三种异常处理

空回滚

在没有调用 TCC 资源 Try 方法的情况下,调用了二阶段的 Cancel 方法,Cancel 方法需要识别出这是一个空回滚,然后直接返回成功。

出现原因:是当一个分支事务所在服务宕机或网络异常,分支事务调用记录为失败,这个时候其实是没有执行Try阶段,当故障恢复后,分布式事务进行回滚则会调用二阶段的Cancel方法,从而形成空回滚。

解决思路是

关键就是要识别出这个空回滚。思路很简单就是需要知道一阶段是否执行,如果执行了,那就是正常回滚;如果没执行,那就是空回滚。

幂等

TCC二阶段提交重试机制不会引发数据不一致,要求 TCC 的二阶段 Try、Confirm 和 Cancel 接口保证幂等,这样不会重复使用或者释放资源。如果幂等控制没有做好,很有可能导致数据不一致等严重问题。

解决思路 在上述“分支事务记录”中增加执行状态,每次执行前都查询该状态。

悬挂

悬挂就是对于一个分布式事务,其二阶段 Cancel 接口比 Try 接口先执行。

出现原因: 在 RPC 调用分支事务try时,先注册分支事务,再执行RPC调用,如果此时 RPC 调用的网络发生拥堵,通常 RPC 调用是有超时时间的,RPC 超时以后,TM就会通知RM回滚该分布式事务,可能回滚完成后,RPC 请求才到达参与者真正执行,而一个 Try 方法预留的业务资源,只有该分布式事务才能使用,该分布式事务第一阶段预留的业务资源就再也没有人能够处理了,对于这种情况,我们就称为悬挂,即业务资源预留后没法继续处理。

解决思路:如果二阶段执行完成,那一阶段就不能再继续执行。在执行一阶段事务时判断在该全局事务下,“分支事务记录”表中是否已经有二阶段事务记录,如果有则不执行Try。

TCC优缺点:

TCC的优点:

● 一阶段完成直接提交事务,释放数据库资源,性能好

● 无需使用全局锁,性能最强

● 不依赖数据库事务,而是依赖补偿操作,可以用于非事务型数据库

TCC的缺点

● 有代码侵入,需要人为编写try、Confirm和Cancel接口,太麻烦

● 软状态,事务是最终一致

● 需要考虑Confirm和Cancel的失败情况,做好幂等处理

这篇关于分布式事务的八种方案解析(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1063177

相关文章

在Java中将XLS转换为XLSX的实现方案

《在Java中将XLS转换为XLSX的实现方案》在本文中,我们将探讨传统ExcelXLS格式与现代XLSX格式的结构差异,并为Java开发者提供转换方案,通过了解底层原理、性能优势及实用工具,您将掌握... 目录为什么升级XLS到XLSX值得投入?实际转换过程解析推荐技术方案对比Apache POI实现编程

Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析

《Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析》InstantiationAwareBeanPostProcessor是Spring... 目录一、什么是InstantiationAwareBeanPostProcessor?二、核心方法解

深入解析 Java Future 类及代码示例

《深入解析JavaFuture类及代码示例》JavaFuture是java.util.concurrent包中用于表示异步计算结果的核心接口,下面给大家介绍JavaFuture类及实例代码,感兴... 目录一、Future 类概述二、核心工作机制代码示例执行流程2. 状态机模型3. 核心方法解析行为总结:三

springboot项目中使用JOSN解析库的方法

《springboot项目中使用JOSN解析库的方法》JSON,全程是JavaScriptObjectNotation,是一种轻量级的数据交换格式,本文给大家介绍springboot项目中使用JOSN... 目录一、jsON解析简介二、Spring Boot项目中使用JSON解析1、pom.XML文件引入依

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

C#代码实现解析WTGPS和BD数据

《C#代码实现解析WTGPS和BD数据》在现代的导航与定位应用中,准确解析GPS和北斗(BD)等卫星定位数据至关重要,本文将使用C#语言实现解析WTGPS和BD数据,需要的可以了解下... 目录一、代码结构概览1. 核心解析方法2. 位置信息解析3. 经纬度转换方法4. 日期和时间戳解析5. 辅助方法二、L

Mybatis Plus JSqlParser解析sql语句及JSqlParser安装步骤

《MybatisPlusJSqlParser解析sql语句及JSqlParser安装步骤》JSqlParser是一个用于解析SQL语句的Java库,它可以将SQL语句解析为一个Java对象树,允许... 目录【一】jsqlParser 是什么【二】JSqlParser 的安装步骤【三】使用场景【1】sql语

Java实现本地缓存的常用方案介绍

《Java实现本地缓存的常用方案介绍》本地缓存的代表技术主要有HashMap,GuavaCache,Caffeine和Encahche,这篇文章主要来和大家聊聊java利用这些技术分别实现本地缓存的方... 目录本地缓存实现方式HashMapConcurrentHashMapGuava CacheCaffe

SpringBoot整合Sa-Token实现RBAC权限模型的过程解析

《SpringBoot整合Sa-Token实现RBAC权限模型的过程解析》:本文主要介绍SpringBoot整合Sa-Token实现RBAC权限模型的过程解析,本文给大家介绍的非常详细,对大家的学... 目录前言一、基础概念1.1 RBAC模型核心概念1.2 Sa-Token核心功能1.3 环境准备二、表结

MySQL 事务的概念及ACID属性和使用详解

《MySQL事务的概念及ACID属性和使用详解》MySQL通过多线程实现存储工作,因此在并发访问场景中,事务确保了数据操作的一致性和可靠性,下面通过本文给大家介绍MySQL事务的概念及ACID属性和... 目录一、什么是事务二、事务的属性及使用2.1 事务的 ACID 属性2.2 为什么存在事务2.3 事务