搜索
首页数据库mysql教程分布式事务的图文详解

分布式事务的图文详解

Dec 15, 2018 am 10:41 AM
javamysql事务分布式事务

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

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

事务

什么是事务?这个作为后端开发,日常开发中只要与数据库有交互,肯定就会使用过事务。现在摘抄一段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 却是牺牲这种强一致性,允许数据短时间内不一致,最终一致性。

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

分布式事务实现方案

  1. 基于数据库资源层面

  • 2PC 两阶段提交协议

  • 3PC 三阶段提交协议

  • 基于业务层面

    • TCC

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

    2PC 两阶段提交协议

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

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

    整个过程如下图。

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

    839156960-5c13a662bdea1_articlex.png

    分布式事务回滚场景:

    3341990279-5c13a662bcf86_articlex.png

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

    相应该方案也存在缺点:

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

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

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

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

    3PC 三阶段提交协议

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

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

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

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

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

  • 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操作要满足幂等性

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

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

    1. 创建订单

    2. 下单

    • 调用余额系统,扣减余额

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

    • 修改订单状态为已支付

    • 完后支付。

    实际过程如下图。

    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 性能较高,可以保证数据最终一致性。但是对于应用层来说,一个方法必须改造成三个方法,且业务中需引入一些中间状态,相对而言应用改造程度较大。

    以上是分布式事务的图文详解的详细内容。更多信息请关注PHP中文网其他相关文章!

    声明
    本文转载于:segmentfault。如有侵权,请联系admin@php.cn删除
    MySQL:世界上最受欢迎的数据库的简介MySQL:世界上最受欢迎的数据库的简介Apr 12, 2025 am 12:18 AM

    MySQL是一种开源的关系型数据库管理系统,主要用于快速、可靠地存储和检索数据。其工作原理包括客户端请求、查询解析、执行查询和返回结果。使用示例包括创建表、插入和查询数据,以及高级功能如JOIN操作。常见错误涉及SQL语法、数据类型和权限问题,优化建议包括使用索引、优化查询和分表分区。

    MySQL的重要性:数据存储和管理MySQL的重要性:数据存储和管理Apr 12, 2025 am 12:18 AM

    MySQL是一个开源的关系型数据库管理系统,适用于数据存储、管理、查询和安全。1.它支持多种操作系统,广泛应用于Web应用等领域。2.通过客户端-服务器架构和不同存储引擎,MySQL高效处理数据。3.基本用法包括创建数据库和表,插入、查询和更新数据。4.高级用法涉及复杂查询和存储过程。5.常见错误可通过EXPLAIN语句调试。6.性能优化包括合理使用索引和优化查询语句。

    为什么要使用mysql?利益和优势为什么要使用mysql?利益和优势Apr 12, 2025 am 12:17 AM

    选择MySQL的原因是其性能、可靠性、易用性和社区支持。1.MySQL提供高效的数据存储和检索功能,支持多种数据类型和高级查询操作。2.采用客户端-服务器架构和多种存储引擎,支持事务和查询优化。3.易于使用,支持多种操作系统和编程语言。4.拥有强大的社区支持,提供丰富的资源和解决方案。

    描述InnoDB锁定机制(共享锁,独家锁,意向锁,记录锁,间隙锁,下一键锁)。描述InnoDB锁定机制(共享锁,独家锁,意向锁,记录锁,间隙锁,下一键锁)。Apr 12, 2025 am 12:16 AM

    InnoDB的锁机制包括共享锁、排他锁、意向锁、记录锁、间隙锁和下一个键锁。1.共享锁允许事务读取数据而不阻止其他事务读取。2.排他锁阻止其他事务读取和修改数据。3.意向锁优化锁效率。4.记录锁锁定索引记录。5.间隙锁锁定索引记录间隙。6.下一个键锁是记录锁和间隙锁的组合,确保数据一致性。

    MySQL查询性能差的常见原因是什么?MySQL查询性能差的常见原因是什么?Apr 12, 2025 am 12:11 AM

    MySQL查询性能不佳的原因主要包括没有使用索引、查询优化器选择错误的执行计划、表设计不合理、数据量过大和锁竞争。 1.没有索引导致查询缓慢,添加索引后可显着提升性能。 2.使用EXPLAIN命令可以分析查询计划,找出优化器错误。 3.重构表结构和优化JOIN条件可改善表设计问题。 4.数据量大时,采用分区和分表策略。 5.高并发环境下,优化事务和锁策略可减少锁竞争。

    您什么时候应该使用复合索引与多个单列索引?您什么时候应该使用复合索引与多个单列索引?Apr 11, 2025 am 12:06 AM

    在数据库优化中,应根据查询需求选择索引策略:1.当查询涉及多个列且条件顺序固定时,使用复合索引;2.当查询涉及多个列但条件顺序不固定时,使用多个单列索引。复合索引适用于优化多列查询,单列索引则适合单列查询。

    如何识别和优化MySQL中的慢速查询? (慢查询日志,performance_schema)如何识别和优化MySQL中的慢速查询? (慢查询日志,performance_schema)Apr 10, 2025 am 09:36 AM

    要优化MySQL慢查询,需使用slowquerylog和performance_schema:1.启用slowquerylog并设置阈值,记录慢查询;2.利用performance_schema分析查询执行细节,找出性能瓶颈并优化。

    MySQL和SQL:开发人员的基本技能MySQL和SQL:开发人员的基本技能Apr 10, 2025 am 09:30 AM

    MySQL和SQL是开发者必备技能。1.MySQL是开源的关系型数据库管理系统,SQL是用于管理和操作数据库的标准语言。2.MySQL通过高效的数据存储和检索功能支持多种存储引擎,SQL通过简单语句完成复杂数据操作。3.使用示例包括基本查询和高级查询,如按条件过滤和排序。4.常见错误包括语法错误和性能问题,可通过检查SQL语句和使用EXPLAIN命令优化。5.性能优化技巧包括使用索引、避免全表扫描、优化JOIN操作和提升代码可读性。

    See all articles

    热AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智能驱动的应用程序,用于创建逼真的裸体照片

    AI Clothes Remover

    AI Clothes Remover

    用于从照片中去除衣服的在线人工智能工具。

    Undress AI Tool

    Undress AI Tool

    免费脱衣服图片

    Clothoff.io

    Clothoff.io

    AI脱衣机

    AI Hentai Generator

    AI Hentai Generator

    免费生成ai无尽的。

    热门文章

    R.E.P.O.能量晶体解释及其做什么(黄色晶体)
    3 周前By尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.最佳图形设置
    3 周前By尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.如果您听不到任何人,如何修复音频
    3 周前By尊渡假赌尊渡假赌尊渡假赌
    WWE 2K25:如何解锁Myrise中的所有内容
    3 周前By尊渡假赌尊渡假赌尊渡假赌

    热工具

    DVWA

    DVWA

    Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

    MinGW - 适用于 Windows 的极简 GNU

    MinGW - 适用于 Windows 的极简 GNU

    这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

    安全考试浏览器

    安全考试浏览器

    Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

    Atom编辑器mac版下载

    Atom编辑器mac版下载

    最流行的的开源编辑器

    mPDF

    mPDF

    mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),