分布式事务解决方案

分布式事务解决方案

花开堪折直须折,莫待无花空折枝。

分布式事务是指事务的操作位于不同的节点上,需要保证事务的ACID特性。在分布式架构下,每个节点只知晓自身操作的成功与失败,无法知悉其他节点的操作状态。当一个事务跨多个节点时,为了保持事务的原子性与一致性,从而引入一个协调者来统一管控所有参与者的操作结果,并指引它们最终是否把操作结果进行诊治的提交(commit)和回滚(rollback)。例如在购物下单场景中,库存和订单如果不在同一个节点上,就涉及分布式事务。

在分布式系统中要实现分布式事务,常见的解决方案有两段提交(2PC)、三段提交(3PC)、事务补偿(TCC)、本地消息表(异步确保)、MQ事务方案(可靠消息事务)、最大努力通知和Saga事务。

1、两阶段提交(2PC)

二阶段提交协议(Two-phase Commit,即 2PC)是常用的分布式事务解决方案,即将事务的提交过程分为准备阶段和提交阶段两个阶段来进行处理,通过引入协调者(Coordinator)来协调参与者的行为,并最终决定这些参与者是否要真正执行事务。

  • 事务协调者(事务管理器):事务的发起者
  • 事务参与者(资源管理器):事务的执行者

准备阶段(投票阶段)

协调者询问参与者事务是否执行成功,参与者发回事务执行结果,但该阶段并未提交事务。

提交阶段(执行阶段)

如果事务在每个参与者上都执行成功,事务协调者发送通知让参与者提交事务;否则,协调者发送通知让参与者回滚事务。

在准备阶段,参与者执行了事务,但是还未提交。只有在提交阶段接收到协调者发来的通知后,才进行提交或者回滚。

2PC优缺

  • 尽量保证了数据的强一致,适合对数据强一致要求很高的关键领域。(其实也不能100%保证强一致,如宕机)

  • 性能问题:执行过程中,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。

  • 可靠性问题:参与者发生故障。协调者需要给每个参与者额外指定超时机制,超时后整个事务失败。协调者发生故障。参与者会一直阻塞下去。需要额外的备机进行容错。
  • 数据一致性问题:二阶段无法解决的问题如协调者在发出 commit消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。
  • 实现复杂:牺牲了可用性,对性能影响较大,不适合高并发高性能场景。

2、三阶段提交(3PC)

三阶段提交协议是二阶段提交协议的改进版本,其有两个改动点。

即除了引入超时机制之外,3PC把2PC的准备阶段再次一分为二,这样三阶段提交就有 CanCommitPreCommit和 DoCommit三个阶段。

3PC优缺点

相比二阶段提交,三阶段提交降低了阻塞范围,在等待超时后协调者或参与者会中断事务。避免了协调者单点问题,阶段 3 中协调者出现问题时,参与者会继续提交事务。

数据不一致问题依然存在,当在参与者收到 preCommit 请求后等待 doCommit 指令时,此时如果协调者请求中断事务,而协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。

3、事务补偿(TCC)

TCC(Try Confirm Cancel)方案是一种应用层面侵入业务的两阶段提交,是目前最火的一种柔性事务方案。TCC采用了补偿机制,其核心思想就是针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。它分为Try、Confirm和Cancel三个阶段。

转账例子:假入 Bob 要向 Smith 转账,思路大概是: 我们有一个本地方法,里面依次调用。

TCC优缺点

跟2PC比起来,实现以及流程相对简单了一些,但数据的一致性比2PC差。

在2和3步中都有可能会失败。TCC属于应用层的一种补偿方式,所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。

4、本地消息表(异步确保

本地消息表方案的核心思路是将分布式事务拆分成本地事务进行处理。通过在事务主动发起方额外新建事务消息表,事务发起方处理业务和记录事务消息在本地事务中完成,轮询事务消息表的数据发送事务消息,事务被动方基于消息中间件消费事务消息表中的事务。

上图中整体的处理步骤如下:

本地消息表优缺点

避免了分布式事务,实现了最终一致性。

消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。

5、MQ事务方案(可靠消息事务)

MQ事务方案是对本地消息表的封装,将本地消息表基于 MQ 内部,其他方面的协议基本与本地消息表一致。

6、最大努力通知

最大努力通知方案是对MQ事务方案的进一步优化。它在事务主动方增加了消息校对的接口,如果事务被动方没有接收到消息,此时可以调用事务主动方提供的消息校对的接口主动获取。

其适用于业务通知类型,例如微信交易的结果,就是通过最大努力通知方式通知各个商户,既有回调通知,也有交易查询接口。

7、Saga事务

Saga 事务基本协议如下:

  • 每个 Saga 事务由一系列幂等的有序子事务(sub-transaction) Ti 组成。
  • 每个 Ti 都有对应的幂等补偿动作 Ci,补偿动作用于撤销 Ti 造成的结果。

Saga 的执行顺序有两种:

  • T1, T2, T3, …, Tn
  • T1, T2, …, Tj, Cj,…, C2, C1,其中0 < j < n

TCC事务补偿机制有一个预留(Try)动作,相当于先报存一个草稿,然后才提交;而Saga事务没有预留动作,直接提交。对于事务异常,Saga提供了向后恢复和向前恢复两种恢复策略。

向后恢复(backward recovery)

backward recovery,即上面提到的第二种执行顺序,其中j是发生错误的sub-transaction,这种做法的效果是撤销掉之前所有成功的sub-transation,使得整个Saga的执行结果撤销。

向前恢复(forward recovery)

forward recovery,即适用于必须要成功的场景,执行顺序是类似于这样的:T1, T2, …, Tj(失败), Tj(重试),…, Tn,其中j是发生错误的sub-transaction。该情况下不需要Ci。

各分布式事务方案的常见使用场景:

  • 2PC/3PC:依赖于数据库,能够很好的提供强一致性和强事务性,但相对来说延迟比较高,比较适合传统的单体应用,在同一个方法中存在跨库操作的情况,不适合高并发和高性能要求的场景。
  • TCC:适用于执行时间确定且较短,实时性要求高,对数据一致性要求高,比如互联网金融企业最核心的三个服务:交易、支付、账务。
  • 本地消息表/MQ 事务:都适用于事务中参与方支持操作幂等,对一致性要求不高,业务上能容忍数据不一致到一个人工检查周期,事务涉及的参与方、参与环节较少,业务上有对账/校验系统兜底。
  • Saga 事务:由于 Saga 事务不能保证隔离性,需要在业务层控制并发,适合于业务场景事务并发操作同一资源较少的情况。Saga 相比缺少预提交动作,导致补偿动作的实现比较麻烦,例如业务是发送短信,补偿动作则得再发送一次短信说明撤销,用户体验比较差。Saga 事务较适用于补偿动作容易处理的场景。

上述几种方案都是分布式事务的理论知识,Seta是分布式解放方案的一个落地实现。

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 ATTCCSAGAXA 事务模式,为用户打造一站式的分布式解决方案。

  • 对业务无侵入:即减少技术架构上的微服务化所带来的分布式事务问题对业务的侵入;
  • 高性能:减少分布式事务解决方案所带来的性能消耗。
  • Seta官方文档:https://seata.io/zh-cn/index.html

花开堪折直须折

莫待无花空折枝

Original: https://www.cnblogs.com/taojietaoge/p/15890289.html
Author: 涛姐涛哥
Title: 分布式事务解决方案

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/612653/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 从前,有一个简单的通道系统叫尤娜……

    从前,有个女生宿舍,住着小A、小B、尤娜和我4个人。有天,小A不小心把小B的床板坐塌了。小B非常生气,当场和小A翻脸。不论人缘最好的尤娜怎么中间调解都不管用。一直到毕业,小A和小B…

    数据库 2023年6月6日
    085
  • 如何有效管理产品生命周期(How to Effectively Manage a Product Lifecycle)

    本文翻译自文章:How to Effectively Manage a Product Lifecycle文章原文链接:https://medium.com/design-boot…

    数据库 2023年6月11日
    0172
  • SQLZOO练习7–Using NULL

    teacher表: iddeptnamephonemobile 101 1 Shrivell 2753 07986 555 1234 102 1 Throd 2754 07122 …

    数据库 2023年5月24日
    076
  • FTP文件上传

    一、配置FTP文件服务器 以Ubuntu为例 FTP两种模式简介 PORT(主动模式)第一步FTP客户端首先随机选择一个大于1024的端口p1,并通过此端口发送请求连接到FTP服务…

    数据库 2023年6月6日
    090
  • 详解 Serverless 架构的 6 大应用场景

    Serverless 架构将成为未来云计算领域重要的技术架构,将会被更多的业务所采纳。进一步深究,Serverless 架构在什么场景下有优秀的表现,在什么场景下可能表现得并不是很…

    数据库 2023年6月14日
    082
  • Spring(一)-初识 + DI+scope

    1、获取bean实例的三种方式 UTF-8 4.3.18.RELEASE 1.16.18 4.11 org.springframework spring-beans ${sprin…

    数据库 2023年6月16日
    078
  • Resilience4j 实践

    微服务设计模式 – circuit breaker circuit breaker 熔断器,在很多不同的领域都有这个定义,例如电路里面的熔断器,股票行业里面的熔断,当然…

    数据库 2023年6月11日
    0101
  • Python日志模块封装

    一、先上结论 对 Python logging模块进行二次封装 -*- coding:utf-8 -*- 作者:IT小学生蔡坨坨 博客:caituotuo.top 时间:2022/…

    数据库 2023年6月11日
    093
  • AUFS:多点合一,写时复制

    AUFS(全称:advanced multi-layered unification filesystem,高级多层统一文件系统),用于为 Linux 文件系统实现 联合挂载。提到…

    数据库 2023年6月6日
    094
  • 一时兴起,写了个寻路代码

    看到一个面试题,是有关寻路的,于是想练练手,自己也写一个。 把地图坐标设计为二维数据,坐标点的值代表不同意义。 先上代码: 1 import java.util.ArrayList…

    数据库 2023年6月14日
    0101
  • Selenium 4 有哪些不一样?

    转载请注明出处❤️ 作者:测试蔡坨坨 原文链接:caituotuo.top/d59b986c.html 你好,我是测试蔡坨坨。 众所周知,Selenium在2021年10月13号发…

    数据库 2023年6月11日
    085
  • SpringBoot下的文件上传

    ; 代码很简单。已经放到码云了,码云地址:https://gitee.com/zhang-zhixi/springboot-upload.git posted @2022-04-2…

    数据库 2023年6月14日
    078
  • ReentrantLock 公平锁源码 第1篇

    ReentrantLock 1 这篇还是接着ReentrantLock的公平锁,没看过第0篇的可以先去看上一篇https://www.cnblogs.com/sunankang/p…

    数据库 2023年6月16日
    0110
  • MySQL实战45讲 11

    11 | 怎么给字符串字段加索引? Q:如何在邮箱这样的字段上建立合理的索引? 用户表的定义: create table SUser( ID bigint unsigned pri…

    数据库 2023年6月16日
    084
  • 无根用户管理podman

    在允许没有root特权的用户运行Podman之前,管理员必须安装或构建Podman并完成以下配置 基础设置 cgroup V2Linux内核功能允许用户限制普通用户容器可以使用的资…

    数据库 2023年6月14日
    080
  • SQL Server2008 Order by在union子句不可直接使用的原因

    按照要求,每个取top 20,既然是随机的取,那么就SQL Server Order by newid()就是了,然后把所有数据union起来就得了。所以我立即给出了答案: sel…

    数据库 2023年6月14日
    073
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球