一文看懂分布式事务

本地事务

事务Transaction由一组SQL组成,具有四个ACID特性

ACID

Atomicity 原子性 构成事务的一组SQL,要么全部生效,要么全不生效,不会出现部分生效的情况

Consistency 一致性 数据库经过事务操作后从一种状态转变为另一个状态。可以说原子性是从行为上描述,而一致性是从结果上描述

isolation 隔离性 事务操作的数据对象 相对于 其他事务操作的数据对象相互隔离,互不影响

durability 持久性 事务提交后,其结果就是永久性的,即使发生宕机(非磁盘损坏)

事务实现

对于MySQL数据库(InnoDB存储引擎)而言,隔离性是通过不同粒度的锁机制来实现事务间的隔离;原子性、一致性和持久性通过redo log 重做日志和undo log回滚日志来保证的。

redo log 当数据库对数据做修改的时候,需要把数据页从磁盘读到buffer pool中,然后在buffer pool中进行修改,那么这个时候buffer pool中的数据页就与磁盘上的数据页内容不一致,称buffer pool的数据页为dirty page 脏数据,如果这个时候发生非正常的DB服务重启,那么这些数据还没在内存,并没有同步到磁盘文件中(注意,同步到磁盘文件是个随机IO),也就是会发生数据丢失,如果这个时候,能够在有一个文件,当buffer pool 中的data page变更结束后,把相应修改记录记录到这个文件(注意,记录日志是顺序IO),那么当DB服务发生crash的情况,恢复DB的时候,也可以根据这个文件的记录内容,重新应用到磁盘文件,数据保持一致。

undo log undo日志用于存放数据被修改前的值,如果修改出现异常,可以使用undo日志来实现回滚操作,保证事务的一致性。另外InnoDB MVCC事务特性也是基于undo日志实现的。undo日志分为insert undo log (insert语句产生的日志,事务提交后直接删除)和 update undo log(delete和update语句产生的日志,由于该undo log可能提供MVVC机制使用,所以不能再事务提交时删除)。

问题引入

CAP理论

CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。但由于在分布式系统中,分区容错性必然存在,所以只能在一致性和可用性妥协。

传统的DBMS,如MySQL其实CA组合,在主从架构下,读写分离的情况下,是牺牲一定的一致性的(主从延迟)。

Base理论

base available 基本可用 分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用

soft state 软状态 允许系统中存在中间状态,这个状态不影响系统可用性

eventually consistent 最终一致性 系统的中间状态经过短暂的时间后到达一致状态

如何解决

场景举例

考虑这样一种业务场景,系统A调用系统B的退款服务进行退款,系统A更改内部退款状态,接着调用系统C的短信服务通知用户。

在这样的一个场景下,由于网络不可靠的必然存在,存在A、B、C三个系统之间一致性的问题。

本地表

针对上述场景,设计两张表 退款记录表短信发送记录表 以及 相应的补偿Job

具体实现过程:

  1. 新增退款记录表,状态为处理中
  2. 调用系统B的退款服务进行退款
  3. 更新退款记录状态为对应的状态(成功/失败)
  4. 如果退款成功,则新增短信发送记录,记录状态为待发送
  5. 调用系统C的短信服务,发送短信
  6. 更新短信发送记录为已发送

退款补偿Job 查询退款记录表中处理中的记录,调用系统B的退款服务 退款成功处理:

  1. 新增短信发送记录,记录状态为待发送
  2. 调用系统C的短信服务,发送短信
  3. 更新短信发送记录为已发送

短信通知补偿Job 查询短信发送记录中待发送的记录,调用系统C的短信服务

  1. 调用系统C的短信服务,发送短信
  2. 更新短信发送记录为已发送

注意:

  • 系统B和系统C需要根据调用方传的uuid支持幂等
  • 系统A、B、C会出现短暂的不一致,但最终一致

事务消息

可以将其视为两阶段提交消息实现,以确保分布式系统中的最终一致性。事务性消息可确保本地事务的执行和消息的发送可以原子方式执行。

但是由于事务消息异步的特性,调用方拿不到消费方的处理结果,适用于不关心对方的返回结果/对方负责保证处理成功

针对上述场景,增加两个事务消息的方式解决一致性问题,系统A通过发送事务消息的方式与系统B和系统C进行交互

具体实现过程:

发送退款的事务消息 新增退款记录,状态:处理中 Commit退款事务消息

提供MQ事务callback 退款callback查询

  • 有退款记录且未处理中则Commit
  • 其他则Rollback

发送短信callback查询

  • 有退款记录且成功则Commit
  • 其他则Rollback

退款同步Job 查询退款记录表中处理中的记录,调用系统B的退款查询接口 同步状态 退款成功处理:

  • 发送退款的事务消息
  • 更新退款记录状态
  • Commit短信事务消息

相关理论

二阶段提交

阻塞问题,参与者将协议消息发送给协调器后,它将阻塞直到收到提交或回滚,只能依赖协调者的超时机制

协调者单点问题,如果协调者出现故障,则某些参与者将一直无法收到提交或回滚的消息。

DTP Model

X / Open分布式事务处理DTP(Distributed Transaction Processing)模型是一种软件体系架构,已经成为事实上的事务模型组件的行为标准。它允许多个应用程序共享由多个资源管理器提供的资源,并允许其工作被协调为全局事务。

ApplicationProgram(AP) 应用程序定义了事务边界并指定构成事务的操作

ResourceManager(RM) 资源管理器用来管理我们需要访问的共享资源,我们可以将它理解为关系数据库、文件存储系统、消息队列、打印机等

TransactionManagger(TM) 事务管理器是一个独立的组件,他为事务分配标识符并监视事务的执行情况,负责事务完成和故障恢复

CommunicationResourceManager(CRM) 通信资源管理器控制一个或多个 TM domain 之间分布式应用的通信。

XA Specification

XA规范是X/Open关于分布式事务处理 (DTP)的规范。规范描述了全局的事务管理器与局部的资源管理器之间的接口。XA规范的目的是允许多个资源(如数据库,应用服务器,消息队列,等等)在同一事务中访问,这样可以使ACID属性跨越应用程序而保持有效。XA使用两阶段提交来保证所有资源同时提交或回滚任何特定的事务。

XA规范描述了资源管理器要支持事务性访问所必需做的事情。

TCC

saga

在 Saga 模式下,分布式事务内有多个参与者,每一个参与者都是一个冲正补偿服务,需要用户根据业务场景实现其正向操作和逆向回滚操作。

分布式事务执行过程中,依次执行各参与者的正向操作,如果所有正向操作均执行成功,那么分布式事务提交。如果任何一个正向操作执行失败,那么分布式事务会去退回去执行前面各参与者的逆向回滚操作,回滚已提交的参与者,使分布式事务回到初始状态。

Saga 模式下分布式事务通常是由事件驱动的,各个参与者之间是异步执行的,Saga 模式是一种长事务解决方案。

Saga模式的优势是:

  • 一阶段提交本地数据库事务,无锁,高性能;
  • 参与者可以采用事务驱动异步执行,高吞吐;
  • 补偿服务即正向服务的“反向”,易于理解,易于实现;

缺点:

  • Saga 模式由于一阶段已经提交本地数据库事务,且没有进行“预留”动作,所以不能保证隔离性。

开源项目

seata

Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。支持AT、TCC、SAGA、XA四种模式,对微服务框架支持友好。

如下图所示,Seata 中有三大模块,分别是 TM、RM 和 TC。 其中 TM 和 RM 是作为 Seata 的客户端与业务系统集成在一起,TC 作为 Seata 的服务端独立部署。

TC - 事务协调者 维护全局和分支事务的状态,驱动全局事务提交或回滚。

TM - 事务管理器 定义全局事务的范围:开始全局事务、提交或回滚全局事务。

RM - 资源管理器 管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

在 Seata 中,分布式事务的执行流程:

  • TM 开启分布式事务(TM 向 TC 注册全局事务记录);
  • 按业务场景,编排数据库、服务等事务内资源(RM 向 TC 汇报资源准备状态 );
  • TM 结束分布式事务,事务一阶段结束(TM 通知 TC 提交/回滚分布式事务);
  • TC 汇总事务信息,决定分布式事务是提交还是回滚;
  • TC 通知所有 RM 提交/回滚 资源,事务二阶段结束;

AT模式

AT 模式是一种无侵入的分布式事务解决方案。在 AT 模式下,用户只需关注自己的“业务 SQL”,用户的 “业务 SQL” 作为一阶段,Seata 框架会自动生成事务的二阶段提交和回滚操作。

一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。 二阶段:提交异步化,非常快速地完成。回滚通过一阶段的回滚日志进行反向补偿。

在一阶段,Seata 会拦截“业务 SQL”,首先解析 SQL 语义,找到“业务 SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”,然后执行“业务 SQL”更新业务数据,在业务数据更新之后,再将其保存成“after image”,最后生成行锁。以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性。

TCC模式

一个分布式的全局事务,整体是 两阶段提交 的模型。全局事务是由若干分支事务组成的,分支事务要满足 两阶段提交 的模型要求,即需要每个分支事务都具备自己的:

一阶段 prepare 行为 二阶段 commit 或 rollback 行为

TCC 模式,不依赖于底层数据资源的事务支持:

一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。 二阶段 commit 行为:调用 自定义 的 commit 逻辑。 二阶段 rollback 行为:调用 自定义 的 rollback 逻辑。

所谓 TCC 模式,是指支持把 自定义 的分支事务纳入到全局事务的管理中。

Saga模式

目前SEATA提供的Saga模式是基于状态机引擎来实现的,机制是:

  1. 通过状态图来定义服务调用的流程并生成 json 状态语言定义文件
  2. 状态图中一个节点可以是调用一个服务,节点可以配置它的补偿节点
  3. 状态图 json 由状态机引擎驱动执行,当出现异常时状态引擎反向执行已成功节点对应的补偿节点将事务回滚 (异常发生时是否进行补偿也可由用户自定义决定)
  4. 可以实现服务编排需求,支持单项选择、并发、子流程、参数转换、参数映射、服务执行状态判断、异常捕获等功能

状态机引擎原理

  • 图中的状态图是先执行stateA, 再执行stateB,然后执行stateC
  • "状态"的执行是基于事件驱动的模型,stateA执行完成后,会产生路由消息放入EventQueue,事件消费端从EventQueue取出消息,执行stateB
  • 在整个状态机启动时会调用Seata Server开启分布式事务,并生产xid, 然后记录"状态机实例"启动事件到本地数据库
  • 当执行到一个"状态"时会调用Seata Server注册分支事务,并生产branchId, 然后记录"状态实例"开始执行事件到本地数据库
  • 当一个"状态"执行完成后会记录"状态实例"执行结束事件到本地数据库, 然后调用Seata Server上报分支事务的状态
  • 当整个状态机执行完成, 会记录"状态机实例"执行完成事件到本地数据库, 然后调用Seata Server提交或回滚分布式事务

作者:VectorJin
链接:https://juejin.im/post/5e066c9ff265da33b0718f89

原文地址:https://www.cnblogs.com/jimoer/p/12113286.html

时间: 2024-08-29 21:38:17

一文看懂分布式事务的相关文章

[转帖]一文读懂分布式架构知识体系(内含超全核心知识大图)

一文读懂分布式架构知识体系(内含超全核心知识大图) https://yq.aliyun.com/articles/721007?spm=a2c4e.11153959.0.0.2f464977X7lSdH 作者 | 晓土  阿里巴巴高级工程师 姊妹篇阅读推荐:<云原生时代,分布式系统设计必备知识图谱(内含22个知识点)> 导读:本文力求从分布式基础理论.架构设计模式.工程应用.部署运维.业界方案这几大方面,介绍基于 MSA(微服务架构)的分布式知识体系大纲,从而对 SOA 到 MSA 进化有着立

一文看懂命令行参数的用法——Python中的getopt神器

一文看懂命令行参数的用法--Python中的getopt神器 参考原文:Python模块之命令行参数解析 - 每天进步一点点!!! - 博客园 https://www.cnblogs.com/madsnotes/articles/5687079.htmlpython getopt使用 - tianzhu123的专栏 - CSDN博客 https://blog.csdn.net/tianzhu123/article/details/7655499在运行程序时,可能需要根据不同的条件,输入不同的命令

[转帖]一文看懂mysql数据库本质及存储引擎innodb+myisam

一文看懂mysql数据库本质及存储引擎innodb+myisam https://www.toutiao.com/i6740201316745740807/ 原创 波波说运维 2019-09-29 00:01:00 概述 今天主要讲下mysql数据库引擎的一些概念和mysql数据库本质,一句话总结: 文件夹-文件:一个数据库其实就是一个的文件夹,数据库里面的表就是文件夹里的一个或者多个文件(根据数据库引擎不同而不同,MyISAM是3个,InnoDB是2.5个) mysql的数据库其实就是存放在M

一文看懂java io系统 (转)

出处:  一文看懂java io系统 学习java IO系统,重点是学会IO模型,了解了各种IO模型之后就可以更好的理解java IO Java IO 是一套Java用来读写数据(输入和输出)的API.大部分程序都要处理一些输入,并由输入产生一些输出.Java为此提供了java.io包 java中io系统可以分为Bio,Nio,Aio三种io模型 关于Bio,我们需要知道什么是同步阻塞IO模型,Bio操作的对象:流,以及如何使用Bio进行网络编程,使用Bio进行网络编程的问题 关于Nio,我们需

一文看懂HashMap

一文看懂HashMap 总所周知HashMap是面试中经常问到的一个知识点,也是判断一个候选人基础是否扎实的标准之一,因为通过HashMap可以引出很多知识点,比如数据结构(数组.链表.红黑树).equals和hashcode方法,除此之外还可以引出线程安全的问题,HashMap是我在初学阶段学到的设计的最为巧妙的集合,里面有很多细节以及优化技巧都值得我们深入学习,话不多说先看看相关的面试题: 默认大小.负载因子以及扩容倍数是多少 底层数据结构 如何处理hash冲突的 如何计算一个key的has

一文读懂分布式架构知识体系(内含超全核心知识大图)

作者 | 晓土  阿里巴巴高级工程师 姊妹篇阅读推荐:<云原生时代,分布式系统设计必备知识图谱(内含22个知识点)> 导读:本文力求从分布式基础理论.架构设计模式.工程应用.部署运维.业界方案这几大方面,介绍基于 MSA(微服务架构)的分布式知识体系大纲,从而对 SOA 到 MSA 进化有着立体的认识:从概念上和工具应用上更近一步了解微服务分布式的本质,身临其境的感受如何搭建全套微服务架构的过程. 关注“阿里巴巴云原生”公众号,回复“分布”,即可下载分布式系统及其知识体系清晰大图! 随着移动互

4张图让你看懂分布式架构从硬件到软件

对于分布式的架构相对很多开发者都是个高大上的项目,其实只要看得懂图精通tcp通信.精通磁盘管理.精通内存管理.精通多线程与并行处理,精通事务(其实事务就是基于tcp通信层所扩展而来的MQ之类的一种IO消息模式而与),当然自己开发一套分布式架构上述的基本技术层面是必须比较精通的才能做到,涉及存储文件仓库或数据库仓库镜像技术其实也是基于tcp通信作为基础,没啥高大上的东西.

从概念到底层技术,一文看懂区块链架构设计

转自:http://www.8btc.com/ebook-blockchain https://blog.csdn.net/lucky_greenegg/article/details/52821924 前言 区块链作为一种架构设计的实现,与基础语言或平台等差别较大.区块链是加密货币背后的技术,是当下与VR虚拟现实等比肩的热门技术之一,本身不是新技术,类似Ajax,可以说它是一种技术架构,所以我们从架构设计的角度谈谈区块链的技术实现. 无论你擅长什么编程语言,都能够参考这种设计去实现一款区块链产

一文看懂大数据的技术生态圈

大数据本身是个很宽泛的概念,Hadoop生态圈(或者泛生态圈)基本上都是为了处理超过单机尺度的数据处理而诞生的.你可以把它比作一个厨房所以需要的各种工具.锅碗瓢盆,各有各的用处,互相之间又有重合.你可以用汤锅直接当碗吃饭喝汤,你可以用小刀或者刨子去皮.但是每个工具有自己的特性,虽然奇怪的组合也能工作,但是未必是最佳选择. 大数据,首先你要能存的下大数据. 传统的文件系统是单机的,不能横跨不同的机器.HDFS(Hadoop Distributed FileSystem)的设计本质上是为了大量的数据