一文看懂分布式事务
Posted 分布式实验室
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一文看懂分布式事务相关的知识,希望对你有一定的参考价值。
Atomicity 原子性,构成事务的一组SQL,要么全部生效,要么全不生效,不会出现部分生效的情况
Consistency 一致性,数据库经过事务操作后从一种状态转变为另一个状态。可以说原子性是从行为上描述,而一致性是从结果上描述
Isolation 隔离性,事务操作的数据对象 相对于 其他事务操作的数据对象相互隔离,互不影响
Durability 持久性,事务提交后,其结果就是永久性的,即使发生宕机(非磁盘损坏)
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机制使用,所以不能再事务提交时删除)。
base available,基本可用,分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用
soft state,软状态,允许系统中存在中间状态,这个状态不影响系统可用性
eventually consistent最终一致性,系统的中间状态经过短暂的时间后到达一致状态
新增退款记录表,状态为处理中
调用系统B的退款服务进行退款
更新退款记录状态为对应的状态(成功/失败)
如果退款成功,则新增短信发送记录,记录状态为待发送
调用系统C的短信服务,发送短信
更新短信发送记录为已发送
新增短信发送记录,记录状态为待发送
调用系统C的短信服务,发送短信
更新短信发送记录为已发送
调用系统C的短信服务,发送短信
更新短信发送记录为已发送
系统B和系统C需要根据调用方传的uuid支持幂等
系统A、B、C会出现短暂的不一致,但最终一致
发送退款的事务消息
新增退款记录,状态为:处理中
Commit退款事务消息
退款callback查询:
有退款记录且为处理中则Commit
其他则Rollback
发送短信callback查询:
有退款记录且成功则Commit
其他则Rollback
发送短信的事务消息
更新退款记录为成功
Commit短信事务消息
阻塞问题,参与者将协议消息发送给协调器后,它将阻塞直到收到提交或回滚,只能依赖协调者的超时机制
协调者单点问题,如果协调者出现故障,则某些参与者将一直无法收到提交或回滚的消息。
解决阻塞问题:将2PC中的第一阶段一分为二,提供了一个CanCommit阶段,此阶段并不锁定资源,这样可以大幅降低了阻塞概率
解决单点问题:在参与者这边也引入了超时机制
ApplicationProgram(AP),应用程序定义了事务边界并指定构成事务的操作
ResourceManager(RM),资源管理器用来管理我们需要访问的共享资源,我们可以将它理解为关系数据库、文件存储系统、消息队列、打印机等
TransactionManagger(TM),事务管理器是一个独立的组件,他为事务分配标识符并监视事务的执行情况,负责事务完成和故障恢复
CommunicationResourceManager(CRM),通信资源管理器控制一个或多个 TM domain 之间分布式应用的通信。
一阶段提交本地数据库事务,无锁,高性能;
参与者可以采用事务驱动异步执行,高吞吐;
补偿服务即正向服务的“反向”,易于理解,易于实现。
Saga模式由于一阶段已经提交本地数据库事务,且没有进行“预留”动作,所以不能保证隔离性。
TC - 事务协调者,维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM - 事务管理器,定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM - 资源管理器,管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
TM开启分布式事务(TM向TC 注册全局事务记录);
按业务场景,编排数据库、服务等事务内资源(RM向TC汇报资源准备状态 );
TM结束分布式事务,事务一阶段结束(TM通知TC提交/回滚分布式事务);
TC汇总事务信息,决定分布式事务是提交还是回滚;
TC通知所有 RM 提交/回滚 资源,事务二阶段结束。
一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
二阶段:提交异步化,非常快速地完成。回滚通过一阶段的回滚日志进行反向补偿。
一阶段prepare 行为
二阶段commit或rollback行为
一阶段prepare行为:调用自定义的prepare逻辑。
二阶段commit行为:调用自定义的commit逻辑。
二阶段rollback行为:调用自定义的rollback逻辑。
通过状态图来定义服务调用的流程并生成json状态语言定义文件
状态图中一个节点可以是调用一个服务,节点可以配置它的补偿节点
状态图json由状态机引擎驱动执行,当出现异常时状态引擎反向执行已成功节点对应的补偿节点将事务回滚 (异常发生时是否进行补偿也可由用户自定义决定)
可以实现服务编排需求,支持单项选择、并发、子流程、参数转换、参数映射、服务执行状态判断、异常捕获等功能
图中的状态图是先执行stateA,再执行stateB,然后执行stateC
"状态"的执行是基于事件驱动的模型,stateA执行完成后,会产生路由消息放入EventQueue,事件消费端从EventQueue取出消息,执行stateB
在整个状态机启动时会调用Seata Server开启分布式事务,并生产xid,然后记录"状态机实例"启动事件到本地数据库
当执行到一个"状态"时会调用Seata Server注册分支事务,并生产branchId,然后记录"状态实例"开始执行事件到本地数据库
当一个"状态"执行完成后会记录"状态实例"执行结束事件到本地数据库,然后调用Seata Server上报分支事务的状态
当整个状态机执行完成, 会记录"状态机实例"执行完成事件到本地数据库,然后调用Seata Server提交或回滚分布式事务
以上是关于一文看懂分布式事务的主要内容,如果未能解决你的问题,请参考以下文章