一文看懂分布式事务

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机制使用,所以不能再事务提交时删除)。

如果你想要学习Java的话,我给你分享一些Java的学习资料,你不用浪费时间到处搜了,从Java入门到精通的资料我都给你整理好了,这些资料都是我做Java这几年整理的Java最新学习路线,Java笔试题,Java面试题,Java零基础到精通视频课程,Java开发工具,Java练手项目,Java电子书,Java学习笔记,PDF文档教程,Java程序员面经,Java求职简历模板等,这些资料对你接下来学习Java一定会带来非常大的帮助,每个Java初学者都必备,请你进我的**Java技术qq交流群127522921**自行下载,所有资料都在群文件里,进去要跟大家多交流学习哦。

问题引入


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短信事务消息

相关理论


二阶段提交

二阶段提交是解决分布式事务问题的重要理论基础,但也存在着明显的问题:

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

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

为了解决二阶段提交出现的问题,又有了三阶段提交(Three-phase commit)

  • 解决阻塞问题:将2PC中的第一阶段一分为二,提供了一个CanCommit阶段,此阶段并不锁定资源,这样可以大幅降低了阻塞概率

  • 解决单点问题:在参与者这边也引入了超时机制

DTP Model

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

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

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

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

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

XA Specification

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

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

TCC

saga

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

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

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

Saga模式的优势是:

  • 一阶段提交本地数据库事务,无锁,高性能;

  • 参与者可以采用事务驱动异步执行,高吞吐;

  • 补偿服务即正向服务的“反向”,易于理解,易于实现;

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

由于细节内容实在太多了,为了不影响文章的观赏性,只截出了一部分知识点大致的介绍一下,每个小节点里面都有更细化的内容!

小编准备了一份Java进阶学习路线图(Xmind)以及来年金三银四必备的一份《Java面试必备指南》

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
32d36.jpg" alt=“img” style=“zoom: 33%;” />

最后

由于细节内容实在太多了,为了不影响文章的观赏性,只截出了一部分知识点大致的介绍一下,每个小节点里面都有更细化的内容!

[外链图片转存中…(img-SVHtedSv-1713434963220)]

小编准备了一份Java进阶学习路线图(Xmind)以及来年金三银四必备的一份《Java面试必备指南》

[外链图片转存中…(img-I6fZBSrT-1713434963220)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值