分布式事务-二阶段提交与三阶段提交

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:

一、二阶段提交算法描述  
在分布式系统中,事务往往包含有多个参与者的活动,单个参与者上的活动是能够保证原子性的,而多个参与者之间原子性的保证则需要通过两阶段提交来实现,两阶段提交是分布式事务实现的关键。

  很明显,两阶段提交保证了分布式事务的原子性,这些子事务要么都做,要么都不做。而数据库的一致性是由数据库的完整性约束实现的,持久性则是通过commit日志来实现的,不是由两阶段提交来保证的。至于两阶段提交如何保证隔离性,可以参考Large-scale Incremental Processing Using Distributed Transactions and Notifications中两阶段提交的具体实现。

  两阶段提交的过程涉及到协调者和参与者。协调者可以看做成事务的发起者,同时也是事务的一个参与者。对于一个分布式事务来说,一个事务是涉及到多个参与者的。具体的两阶段提交的过程如下: 
第一阶段: 
首先,协调者在自身节点的日志中写入一条的日志记录,然后所有参与者发送消息prepare T,询问这些参与者(包括自身),是否能够提交这个事务; 
参与者在接受到这个prepare T 消息以后,会根据自身的情况,进行事务的预处理,如果参与者能够提交该事务,则会将日志写入磁盘,并返回给协调者一个ready T信息,同时自身进入可提交状态;如果不能提交该事务,则记录日志,并返回一个not commit T信息给协调者,同时撤销在自身上所做的数据库改; 
第二阶段: 
协调者会收集所有参与者的意见。(1)如果收到参与者发来的not commit T信息,则标识着该事务不能提交,协调者会将Abort T 记录到日志中,并向所有参与者发送一个Abort T 信息,让所有参与者撤销在自身上所有的预操作;(2)如果协调者收到所有参与者发来prepare T信息,那么协调者会将Commit T日志写入磁盘,并向所有参与者发送一个Commit T信息,提交该事务。(3)若协调者迟迟未收到某个参与者发来的信息,则认为该参与者发送了一个VOTE_ABORT信息,从而取消该事务的执行。 
参与者接收到协调者发来的Abort T信息以后,参与者会终止提交,并将Abort T 记录到日志中;如果参与者收到的是Commit T信息,则会将事务进行提交,并写入记录。

二、可能出现的问题 
一般情况下,两阶段提交机制都能较好的运行,但可能出现下面三种问题: 
(1)协调者不宕机,参与者宕机; 
(2)协调者宕机,参与者不宕机; 
(3)协调者宕机,参与者也宕机; 
对于(1),当在事务进行过程中,有参与者宕机时,他重启以后,可以通过询问其他参与者或者协调者,从而知道这个事务到底提交了没有。当然,这一切的前提都是各个参与者在进行每一步操作时,都会事先写入日志。 
对于(2),协调者宕机后,可以起新的协调者,然后查询所有参与者的状态是否有commit的,如果有,则继续commit,如果都没有,则abort。 
对于(3),是唯一一个两阶段提交不能解决的困境是:当协调者在发出commit T消息后宕机了,而唯一收到这条命令的一个参与者也宕机了,这个时候这个事务就处于一个未知的状态,没有人知道这个事务到底是提交了还是未提交,从而需要数据库管理员的介入,防止数据库进入一个不一致的状态。当然,如果有一个前提是:所有节点或者网络的异常最终都会恢复,那么这个问题就不存在了,协调者和参与者最终会重启,其他节点也最终也会收到commit T的信息。 
对于上面的困境,业界提出了三阶段提交的方法来此问题,即将二阶段提交的第二阶段再分为待定阶段(或预提交阶段)和确定阶段,从而变为三阶段;在待定阶段协调者log prepare_commit消息后向所有参与者发送prepare_commit消息, 待收到所有参与者回包(这里的回包结果只会成功)或超时时就进入第三段阶,log commit消息并向所有参与者发送commit消息。如果在待定阶段和确定阶段出现协调者和部分参与者同时宕机(即上面的困境),只要存活的协调者或参与者里有prepare_commit或commit消息,新的协调者可以继续进行commit消息,如果没有,就不commit消息,从而保证数据的一致性。

3 日志 
数据库日志保证了事务执行的原子性和持久性,日志类型可以分为redo log,undo log,undo/redo log。

4 总结 
二阶段提交和三阶段提交都是很好的分布式事务算法,三阶段提交是为解决二阶段提交未解决的问题(协调者宕机,参与者也宕机)而提出来的。不过这两种算法都只考虑一个协调者(主节点)的情况,没有考虑多个协调者和如何选出协调者的问题。而另一种知名分布式事务算法pasox能解决多个协调者的情况,并提出了多数派的概念。






本文转自里冲51CTO博客,原文链接:http://blog.51cto.com/coollast/1886506 ,如需转载请自行联系原作者


相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
关系型数据库 MySQL 数据库
Windows安装MySQL数据库
本文介绍如何在Windows安装MySQL数据库。
312 0
|
监控 Java 数据库连接
OceanBase数据库常见问题之observer 启动失败如何解决
OceanBase 是一款由阿里巴巴集团研发的企业级分布式关系型数据库,它具有高可用、高性能、可水平扩展等特点。以下是OceanBase 数据库使用过程中可能遇到的一些常见问题及其解答的汇总,以帮助用户更好地理解和使用这款数据库产品。
|
SQL 缓存 关系型数据库
OBCP题目及解析
OBCP题目及解析
1422 0
|
10月前
|
Kubernetes 应用服务中间件 nginx
【赵渝强老师】K8s中Pod探针的TCPSocketAction
在K8s集群中,kubelet通过探针(如livenessProbe、readinessProbe和startupProbe)检查容器健康状态。探针支持HTTPGetAction、ExecAction和TCPSocketAction三种检查方法。本文重点介绍TCPSocketAction,它通过尝试建立TCP连接来检测容器的健康状况。示例中创建了一个Nginx Pod,并配置了两个探针(readinessProbe和livenessProbe),它们每隔5秒检查一次容器的8080端口,首次检查在启动后10秒进行。若连接失败,容器将重启。视频讲解和命令演示进一步详细说明了这一过程。
377 83
【赵渝强老师】K8s中Pod探针的TCPSocketAction
|
UED 开发者 容器
鸿蒙next版开发:ArkTS组件通用属性(位置设置)
在HarmonyOS next中,ArkTS提供了align、direction、position、markAnchor、offset和alignRules等通用属性,用于精确控制组件在用户界面中的位置和布局。本文详细解读了这些属性,并提供了示例代码进行说明。通过这些属性,开发者可以实现精确布局、动态界面调整和提升用户体验。
1545 6
|
编解码 搜索推荐 API
通义万相文本绘图与人像美化解决方案体验与评估
通义万相提供详尽文档和简易API调用,适合新手部署。服务集成便捷,响应迅速,模型泛化能力强,支持多样化风格,生成图片质量高。建议增强交互式编辑、多语言支持及智能推荐功能。相比竞品,通义万相成本控制优秀,易用性强,适用范围广泛。
481 8
|
前端开发 关系型数据库 MySQL
com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver 的区别
这篇文章讨论了`com.mysql.jdbc.Driver`和`com.mysql.cj.jdbc.Driver`两个MySQL驱动类的区别,指出`com.mysql.jdbc.Driver`适用于MySQL 5的`mysql-connector-java`版本,而`com.mysql.cj.jdbc.Driver`适用于MySQL 6及以上版本的`mysql-connector-java`。文章还提到了在实际使用中如何根据MySQL版本选择合适的驱动类。
com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver 的区别
|
Kubernetes API 开发工具
在K8S中,Deployment的升级过程是什么?
在K8S中,Deployment的升级过程是什么?
|
Java API 数据库
使用Spring Boot构建RESTful API
使用Spring Boot构建RESTful API
|
网络协议 Unix Linux
TCP 三次握手、四次断开
TCP 三次握手、四次断开