分布式事务的图文详解

本篇文章给大家带来的内容是关于分布式事务的图文详解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

这次使用分布式事务框架过程中了学习了一些分布式事务知识,所以本文我们就来聊聊分布式事务那些事。首先我们先回顾下什么是事务。

事务

什么是事务?这个作为后端开发,日常开发中只要与数据库有交互,肯定就会使用过事务。现在摘抄一段wiki的解释,解释下什么是事务。

是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成

数据库系统具有事务特性,这是其有别与文件系统重要特性。传统的文件系统,如果正在写文件,操作系统突然崩溃,此时文件可能被破坏。数据库系统引入事务特性,可以保证数据库从一种状态转换为另一种状态。在提交工作时,可以确保要么所有修改都被保存,要么所有都不保存。

通常一个事务会有多个读写操作构成。

事务具有四个基本特性,俗称ACID。

A(Atomicity):原子性。事务会被当做一个整体,要么所有语句都成功,要么都失败,不能存在部分语句成功,部分失败的情况。

C(Consistenc):一致性。数据库的状态从一种状态转变为另外一种状态,事务开始之前和是事务结束之后,数据库完整性约束不变。什么叫数据库完整性约束不变?举个例子,若一个表姓名字段为唯一约束,若在事务提交或回滚后,姓名字段变成非唯一了,这就破坏数据库的完整性约束。

I(Isolation):隔离性。多个并发事务执行,互不影响。

D(Durability):持久性。事务提交之后,其对数据库相关修改能永久保存在数据库。所以该特性需要数据库系统可以在崩溃时需要恢复时也能提交的数据都不丢失。

因此早期我们的系统只在存在一个数据源情况下,这个时候可以依靠数据库系统事务来保证业务的正确性。

但是随着业务的不断扩展,我们业务的一个单表可能就存在千万数据,在使用再使用一个数据库实例,就会可能存在性相关能问题。这个时候我们就会考虑分库分表。但是这样就有可能导致,单个应用连接多个数据源的情况。如下图示例。

3380161631-5c13a662c6272_articlex.png

上图一次购买过程,商家余额表与用户余额表处于两个单独的数据库实例中,这样单独的事务能保证扣减商家余额或用户余额要么扣减成功,要么扣减失败。但是我们却无法保证两个事务同时成功或同时失败。

还有一种情况,随着系统越来越庞大,我们会选择将系统应用拆分多个微服务,让单个应用只操作一个数据源。这个时候我们就会碰到,一次业务调用,将会调用多个应用,每个应用单独操作数据源的情况,如下图。

3914435811-5c13a662c0526_articlex.png

这种情况下我们更加不能保证所有调用都成功。

由上面的例子下我们可以看出,随着业务发展,传统的单机事务已经无法满足我们的业务的需求,这个时候我们就需要分布式事务来保证。

分布式事务

摘抄一段 wiki 上解释。

A distributed transaction is a database transaction in which two or more network hosts are involved.

我们先来讲下实现分布式事务一些理论基础。

分布式事务技术理论

CAP 定理。在一个分布式系统(指互相连接并共享数据的节点的集合)中,当涉及读写操作时,只能保证一致性(Consistence)、可用性(Availability)、分区容错性(Partition Tolerance)三者中的两个,另外一个必须被牺牲。

摘录极客时间从0开始学架构第22章解释

虽然 CAP 理论定义是三个要素中只能取两个,但放到分布式环境下来思考,我们会发现必须选择 P(分区容忍)要素,因为网络本身无法做到 100% 可靠,有可能出故障,所以分区是一个必然的现象。如果我们选择了 CA 而放弃了 P,那么当发生分区现象时,为了保证 C,系统需要禁止写入,当有写入请求时,系统返回 error(例如,当前系统不允许写入),这又和 A 冲突了,因为 A 要求返回 no error 和 no timeout。因此,分布式系统理论上不可能选择 CA 架构,只能选择 CP 或者 AP 架构

BASE 理论,分别是以下三个单词的缩写。

Basically Available(基本可用):分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用。

Soft state(软状态):允许系统中存在中间状态,这个状态不影响系统可用性,这里指的是CAP中的不一致。

Eventually consistent(最终一致性):最终一致是指经过一段时间后,所有节点数据都将会达到一致。

BASE 是对CAP 中 AP 方案的一种补充。在 BASE 中用软状态和最终一致,保证了延迟后的一致性。BASE 和 ACID 是相反的,ACID 是一种强一致性模型,而 BASE 却是牺牲这种强一致性,允许数据短时间内不一致,最终一致性。

接下来我们看看分布式事务有哪几种实现方案。

分布式事务实现方案

基于数据库资源层面

2PC 两阶段提交协议

3PC 三阶段提交协议

基于业务层面

TCC

基于数据库资源层面实现方案,由于存在多个事务,我们需要存在一个角色管理各个事务的状态。我们将这个角色称为协调者,事务参与者称为参与者。参与者与协调者一般会基于某种特定协议,目前比较有名的为 XA 接口协议。基于协调者与参与者的思想设定,分别提出了 2PC 与 3PC 实现XA 分布式事务。

2PC 两阶段提交协议

如名字所知,这个过程主要分为两步。

第一阶段,协调者(事务管理器)将涉及到事务的进行预提交,这个时候数据库资源开始被锁定。参与者将 undo 与 redo 写入事务日志。
第二阶段,参与者(资源管理器)行提交事务,或者利用 undo 日志回滚事务,释放资源。

整个过程如下图。

分布式事务提交成功场景:

839156960-5c13a662bdea1_articlex.png

分布式事务回滚场景:

3341990279-5c13a662bcf86_articlex.png

该方案的优点为:实现比较简单,主流数据库都支持,强一致性。MySQL 5.5 以后基于 XA 协议实现.

相应该方案也存在缺点:

协调者的单点问题。若协调者在提交阶段宕机,参与者一直在等待,就一直锁定资源,一直阻塞。虽然可以重新选举协调者,但是无法解决该问题。

同步阻塞时间过长,整个执行过程事务是阻塞的,直到提交完成,释放资源,若在提交过程/回滚过程,因为网络延时,参与者一直未收到指令,则参与者一直被阻塞。

数据不一致。第二阶段,协调者发出第一个提交信号后后宕机,则第一个参与者提交事务,第二个参与者因为未收到协调者信号,无法进行事务提交。

于是针对 2PC 存在的缺点,提出改进方案,3PC。

3PC 三阶段提交协议

三阶段提交,在两阶段提交的基础下,改进两阶段。三阶段步骤如下。

CanCommit,协调者询问参与者是否可以进行事务提交。

PreCommit ,若所有参与者可以进行事务提交,协调者下达 PreCommit 命令,参与者锁定资源,并等待最终命令。

所有参与者返回确认信息,协调者向各个事务下发事务执行通知,锁定资源,并将执行情况返回。

部分参与者返回否认信息或协调者等待超时。这种情况,协调者认为事务无法正常执行,下发中断指令,各个参与者退出预备状态

火山写作 火山写作

字节跳动推出的中英文AI写作、语法纠错、智能润色工具,是一款集成创作、润色、纠错、改写、翻译等能力的中英文 AI 写作助手。

火山写作 166 查看详情 火山写作

Do Commit,若第二阶段全部回应 ack,则下达 Do Commit ,进行事务最终提交,否则下达中断事务命令,所有参与者进行事务回滚。

所有参与者正常执行执行事务,协调者下发最终提交指令,释放锁定资源。

部分参与者执行事务失败,协调者等待超时,协调者下发回滚指令,释放锁定资源。

具体见下图。

2774108749-5c13a662aa488_articlex.png

三阶段提交对比两阶段,引入超时机制减少事务阻塞,解决单点故障。在第三阶段,一旦参与者无法接受到协调者信号时,等待超时之后,参与者默认执行 commit,释放资源。

三阶段任然不能解决数据一致性问题。若协调者发出回滚命令,但是由于网络问题,参与者在等待时间内都无法接收到,这时参与者默认提交事务,而其他事务进行了回滚,造成事务不一致。

TCC

TCC 事务

为了解决在事务运行过程中大颗粒度资源锁定的问题,业界提出一种新的事务模型,它是基于业务层面的事务定义。锁粒度完全由业务自己控制。它本质是一种补偿的思路。它把事务运行过程分成 Try、Confirm / Cancel 两个阶段。在每个阶段的逻辑由业务代码控制。这样就事务的锁粒度可以完全自由控制。业务可以在牺牲隔离性的情况下,获取更高的性能。

TCC 分别为 Trying,Confirm,Cancel 三个单词缩写。不同于 2PC 与 3PC 基于数据库层面,TCC 基于应用层面。
TCC 三个动作分别为:

Trying:

完成所有业务检查(一致性)

预留必须业务资源(准隔离性)

Confirm:

真正执行业务

Confirm操作要满足幂等性

Cancel:

释放Try阶段预留的业务资源

Cancel操作要满足幂等性

上面说法,一听起来有点生涩难懂,没关系我们使用实际案例解释。

下面我们模拟商城一次支付过程。用户下单使用组合支付,即余额加红包支付。一次正常流程为:

创建订单

下单

调用余额系统,扣减余额

调用红包系统,扣减红包余额

修改订单状态为已支付

完后支付。

实际过程如下图。

2991593568-5c13a6624164d_articlex.jpg

但是这么一个支付过程调用多个子服务,我们不能保证所有服务都能成功,比如我们在调用红包系统扣减红包系统失败。这个时候我们就碰到尴尬的场景,由于红包服务失败,导致方法异常退出,这个时候订单状态为初始状态,但是用户余额已经扣减。这对用户体验非常不友好。所以这次支付过程,我们必须存在机制将这次过程当成一次整体的行为,必须保证这其中服务调用,要么都成功,要么都失败,成为一个整体的事务。

2917041632-5c13a66241221_articlex.png

这时我们可以引入 TCC 事务,将整个下单过程作为一个整体。引入后,由于余额系统扣减是失败,这个时候我们回滚订单系统与红包系统。整个过程如下图。

2122053947-5c13a662308ac_articlex.jpg

由于余额系统的失败,我们需要撤销这次过程中所有更改,所以我们向订单系统发送撤销通知,向红包系统发出撤销通知。

因此系统引入 TCC 事务后,我们需要改造我们的调用过程。

系统如何引入 TCC 事务

根据 TCC 事务三步,这个时候我们必须将各个服务改造成 Try Confirm Cancle 三步、

TCC TRY:

根据上面的业务,订单系统增加 try 方法将订单状态修改成 PAYING。余额系统增加一个 try 方法,先检查用于余额是否充足,然后先将余额扣减,然后将扣减的余额增加到冻结金额。红包系统同余额系统。从改造过程可以看出,TCC try 方法需检查各业务资源,且这过程需要引入中间状态。我们根据下图来看整个过程。

1070809020-5c13a6624313f_articlex.png

TCC Confirm:

TCC 第一步 TRY 如果所有子服务调用都成功,这个时候我们就需要确认各服务。各个服务增加 confirm 方法。如余额系统 confirm 方法用来将冻结金额置为0,红包系统如上。订单系统将订单状态修改为 SUCCESS。confirm 方法需要注意实现幂等。如订单系统更新前,一定要先判断该笔订单状态处于 PAYING,才能更新订单。整个过程如下图。

502069117-5c13a66254820_articlex.jpg

讲到这里,必须用到 TCC 事务框架推动各服务。TCC 事务管理器感知到 TRY 方法结束后,自动调用各服务提供的 confirm 方法,将各服务状态修改为终态。

TCC Cancle:

如若 TCC Try 过程中,冻结红包方法失败,这时我们就需要将之前修改都撤销,修改成其初始状态。cancle 方法也需要实现幂等如 confirm 方法 如下图:

502069117-5c13a66254820_articlex.jpg

看到这,我们我们可以看出 TCC Try 成功,confirm 必定要成功,try 失败,cancle 必定要成功。因为 confirm 是系统更新为终态的关键。但是现实这么无情,生产系统 confirm 或 cancle 肯定会有几率失败,这个时候就需要 TCC 框架记录调用 confirm 结果。如果 confirm 调用失败,TCC 框架需要记录下来,然后间隔一定时间再次去调用。

总结与思考

看完全文,基本上对分布式事务又一定了解了吧。

我们基于此对此总结下。使用分布式事务,我们需要结合我们实际场景应用。

如果业务还处于开始阶段,我们其实可以选择数据库事务来保证快速上线迭代。

等到业务一定阶段,系统开始拆分,数据库也拆分,这时如果业务需要保证一致性,这时必须使用分布式事务。这时候使用分布式事务,我们需要基于业务考虑使用哪种。

使用 2PC 或 3PC 实现的分布式框架,业务应用层无需改动,接入较简单。但是相对应能较低,数据资源锁定较长。不太适合互联网等高并发业务场景。

而使用基于 TCC 实现分布式框架,相对 2PC 性能较高,可以保证数据最终一致性。但是对于应用层来说,一个方法必须改造成三个方法,且业务中需引入一些中间状态,相对而言应用改造程度较大。

以上就是分布式事务的图文详解的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/785570.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
java二维数组里怎么任意输入
上一篇 2025年11月26日 11:39:06
豆包的功耗如何
下一篇 2025年11月26日 11:39:14

相关推荐

  • 如何用SumoPaint的AI裁剪图片?快速完成智能图片裁剪教程

    如何用SumoPaint的AI裁剪图片?快速完成智能图片裁剪教程如何用SumoPaint的AI裁剪图片?快速完成智能图片裁剪教程如何用SumoPaint的AI裁剪图片?快速完成智能图片裁剪教程如何用SumoPaint的AI裁剪图片?快速完成智能图片裁剪教程

    答案:SumoPaint虽无AI裁剪功能,但可通过魔棒、套索工具精确选区,结合图层蒙版与羽化、反选等操作实现智能裁剪效果,最后按需导出PNG或JPG高质量文件。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜ 在SumoPaint中,虽然它不…

    2026年9月21日 用户投稿
    000
  • Java OOP如何使用内部类提高代码组织性

    内部类提升Java代码组织性与封装性,成员内部类增强封装,静态内部类分离逻辑,局部与匿名内部类简化回调,私有内部类隐藏实现细节。 内部类在Java面向对象编程中是一种有效提升代码组织性和封装性的工具。通过将一个类定义在另一个类的内部,可以更好地表达类之间的逻辑关系,控制访问权限,并减少命名冲突。合理…

    2026年9月21日
    000
  • MySQL缓存机制对性能提升的作用_MySQL缓存配置及调优方案

    MySQL缓存机制对性能提升的作用_MySQL缓存配置及调优方案MySQL缓存机制对性能提升的作用_MySQL缓存配置及调优方案MySQL缓存机制对性能提升的作用_MySQL缓存配置及调优方案MySQL缓存机制对性能提升的作用_MySQL缓存配置及调优方案

    mysql的缓存机制主要包括innodb缓冲池、查询缓存和操作系统文件系统缓存等,其中innodb缓冲池是性能优化的核心。1. innodb缓冲池缓存表数据和索引页,减少磁盘i/o,提升读写效率;2. 查询缓存因失效频繁及锁竞争问题,在高并发场景下易成瓶颈,已在mysql 8.0中移除;3. 操作系…

    2026年9月21日 用户投稿
    100
  • VSCode中竖线怎么设置_VSCode编辑区竖线(标尺)显示与配置教程

    在VSCode中启用垂直标尺需修改settings.json文件中的editor.rulers属性,如设置{ “editor.rulers”: [80, 120] }可在第80和120列显示竖线,提升代码对齐与可读性;虽原生不支持自定义颜色样式,但可通过安装Guides或In…

    2026年9月21日
    100
  • PHP 数组值比较与嵌套数组过滤教程

    本教程详细讲解如何在 PHP 中比较一个简单数组与一个复杂嵌套数组,并根据特定条件(如文件名匹配)过滤嵌套数组中的所有相关子数组。我们将通过识别非匹配项的索引,然后从所有子数组中移除这些项并重新索引,实现精确的数据筛选。 问题背景 在 php 开发中,我们经常会遇到需要处理结构复杂的数组数据。例如,…

    2026年9月21日
    100
  • Java集合框架在数据处理中的应用实例

    使用Set去重:通过LinkedHashSet去除标签重复并保持顺序;2. Map统计频次:利用HashMap统计单词出现次数;3. List结合Comparator排序:按年龄升序、姓名降序排列用户;4. 集合嵌套处理数据:用Map组织部门与员工列表。集合框架提升数据处理效率与代码可读性。 Jav…

    2026年9月21日
    000
  • Chrome浏览器怎么开启数据同步功能_Chrome浏览器跨设备数据同步设置教程

    首先登录Google账户启用Chrome同步功能,确保书签、历史记录、密码等数据跨设备一致;接着在设置中自定义同步内容类型以满足隐私需求;然后通过Google账户密钥或自定义密码加密同步数据,提升安全性;最后在新设备登录同一账户,自动接收已同步的浏览数据,实现无缝体验。 如果您希望在不同设备间无缝使…

    2026年9月21日
    000
  • 如何使用XGBoost训练AI大模型?优化机器学习模型的步骤

    XGBoost并非用于训练GPT类大模型,而是擅长处理结构化数据的高效梯度提升算法,其优势在于速度快、准确性高、支持并行计算、内置正则化与缺失值处理,适用于表格数据建模;通过分阶段超参数调优(如学习率、树深度、采样策略)、结合贝叶斯优化与交叉验证,并配合特征工程、数据预处理和集成学习等关键步骤,可显…

    2026年9月21日
    000
  • MySQL全文搜索如何与外部引擎结合_提升搜索体验?

    MySQL全文搜索如何与外部引擎结合_提升搜索体验?MySQL全文搜索如何与外部引擎结合_提升搜索体验?MySQL全文搜索如何与外部引擎结合_提升搜索体验?MySQL全文搜索如何与外部引擎结合_提升搜索体验?

    mysql 的全文搜索在中文分词和复杂查询上存在局限,常结合外部引擎提升性能。1. 使用 elasticsearch,通过 logstash 或 canal 同步数据,安装中文分词插件并利用布尔查询等优化搜索。2. 利用 sphinx,从 mysql 直接构建索引,通过 sql-like 接口和中文…

    2026年9月21日 用户投稿
    000
  • VSCode远程开发:配置容器与SSH连接的最佳实践解析

    使用VSCode远程开发提升效率,通过Remote-Containers和Remote-SSH实现环境标准化。1. 配置.devcontainer文件夹,用devcontainer.json定义容器环境,推荐自定义Dockerfile并预装工具;2. SSH连接需配置公钥认证、~/.ssh/conf…

    2026年9月21日
    100
  • 如何在Java中配置与数据库连接环境

    答案:Java中配置数据库连接需引入JDBC驱动,如MySQL在Maven中添加对应依赖;通过DriverManager或连接池(如HikariCP)获取Connection,使用try-with-resources管理资源;建议将连接参数存入properties文件,并处理常见问题如驱动加载、权限…

    2026年9月21日
    000
  • PHP错误日志怎么查看_PHP错误日志定位与查看方法

    要查看PHP错误日志,首先确定php.ini中error_log路径,若未设置则检查Web服务器(如Apache/Nginx)错误日志;确保log_errors=On、error_reporting合理配置,并通过tail、grep等工具分析日志,结合框架日志和系统日志(如syslog)全面定位问题…

    2026年9月21日
    200
  • MySQL的binlog格式有哪些类型_它们有什么区别和影响?

    MySQL的binlog格式有哪些类型_它们有什么区别和影响?MySQL的binlog格式有哪些类型_它们有什么区别和影响?MySQL的binlog格式有哪些类型_它们有什么区别和影响?MySQL的binlog格式有哪些类型_它们有什么区别和影响?

    mysql的binlog有三种格式:statement-based(sbl)、row-based(rbl)和mixed-based(mbl),它们分别记录sql语句、行变更和智能混合方式。1. sbl记录执行的sql,优点是日志小、可读性强,但存在不确定性导致主从不一致;2. rbl记录每行的具体变…

    2026年9月21日 用户投稿
    100
  • VSCode怎么运行全部代码_VSCode批量执行代码教程

    在VSCode里“运行全部代码”或“批量执行代码”,其实很少是一个单一的、所有语言通用的按钮。它更多的是指根据你项目的具体需求,通过配置任务(Tasks)、使用集成终端(Integrated Terminal)配合脚本,或者利用特定语言的运行/调试配置(Launch Configurations)来…

    2026年9月21日
    100
  • TuxPaint的AI工具怎么裁剪图片?教你轻松完成图片裁剪步骤

    TuxPaint的AI工具怎么裁剪图片?教你轻松完成图片裁剪步骤TuxPaint的AI工具怎么裁剪图片?教你轻松完成图片裁剪步骤TuxPaint的AI工具怎么裁剪图片?教你轻松完成图片裁剪步骤TuxPaint的AI工具怎么裁剪图片?教你轻松完成图片裁剪步骤

    TuxPaint没有AI裁剪工具,只能通过橡皮擦或填充工具手动模拟裁剪效果,适合儿童创意绘画但不适合精确图像编辑。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜ TuxPaint作为一个面向儿童的绘画软件,其实并没有专门的“AI工具”来执行…

    2026年9月21日 用户投稿
    100
  • Java Executors类提供哪些线程池方法

    Executors类提供创建线程池的静态方法:newFixedThreadPool创建固定大小线程池,适用于稳定负载;newCachedThreadPool创建可缓存线程池,适合短期异步任务;newSingleThreadExecutor创建单线程池,保证任务顺序执行;newScheduledThr…

    2026年9月21日
    200
  • Windows&Linux双系统安装流程

    Windows&Linux双系统安装流程Windows&Linux双系统安装流程Windows&Linux双系统安装流程Windows&Linux双系统安装流程

    大家好,很高兴再次见到大家,我是你们的朋友全栈君。 注意事项:在安装Windows与Linux双系统时,建议先安装Windows系统,否则可能会导致grub引导被覆盖的问题。 Windows 10系统安装 制作启动盘(优启通链接)https://www.php.cn/link/219b87ff108…

    2026年9月21日 用户投稿
    200
  • MySQL性能模式监控资源_MySQL瓶颈定位精确工具

    MySQL性能模式监控资源_MySQL瓶颈定位精确工具MySQL性能模式监控资源_MySQL瓶颈定位精确工具MySQL性能模式监控资源_MySQL瓶颈定位精确工具MySQL性能模式监控资源_MySQL瓶颈定位精确工具

    mysql性能模式通过事件记录精准定位瓶颈,核心步骤包括:1.启用并配置performance schema,选择性开启消费者和仪器;2.监控等待事件、sql语句、阶段、i/o、内存及锁等关键指标;3.分析events_waits_summary_global_by_event_name等表识别资源…

    2026年9月21日 用户投稿
    000
  • PHP PDO lastInsertId() 返回 0 的原因与解决方案

    在使用 PHP PDO 的 lastInsertId() 方法时,如果意外返回 0,通常是因为在执行 INSERT 语句后,又创建了一个新的数据库连接实例来调用 lastInsertId()。lastInsertId() 依赖于在同一数据库会话中获取最后插入的自增 ID。本文将深入解析此问题,并提供…

    2026年9月21日
    500
  • 三星在电视端首发Perplexity AI应用程序,带来更具创新性AI体验

    10 月 23 日消息,三星电子于美国当地时间 21 日宣布,率先在电视终端推出 perplexity ai 应用程序,为三星电视用户带来更富创新的 ai 使用体验。 借助该应用程序,用户在安排日常生活、查找特定影视内容、创建梦幻体育联赛阵容或策划万圣节活动等场景中,可获得 AI 以卡片式回复框形式…

    2026年9月21日
    500

发表回复

登录后才能评论
关注微信