第一阶段:投票该阶段的主要目的在于打探数据库集群中的各个参与者是否能够正常的执行事务 , 具体步骤如下:
- 协调者向所有的参与者发送事务执行请求 , 并等待参与者反馈事务执行结果;
- 事务参与者收到请求之后 , 执行事务但不提交 , 并记录事务日志;
- 参与者将自己事务执行情况反馈给协调者 , 同时阻塞等待协调者的后续指令 。
- 所有的参与者都回复能够正常执行事务 。
- 一个或多个参与者回复事务执行失败 。
- 协调者等待超时 。
- 协调者向各个参与者发送 commit 通知 , 请求提交事务;
- 参与者收到事务提交通知之后执行 commit 操作 , 然后释放占有的资源;
- 参与者向协调者返回事务 commit 结果信息 。
文章插图
对于第 2 和第 3 种情况 , 协调者均认为参与者无法成功执行事务 , 为了整个集群数据的一致性 , 所以要向各个参与者发送事务回滚通知 , 具体步骤如下:
- 协调者向各个参与者发送事务 rollback 通知 , 请求回滚事务;
- 参与者收到事务回滚通知之后执行 rollback 操作 , 然后释放占有的资源;
- 参与者向协调者返回事务 rollback 结果信息 。
文章插图
两阶段提交协议解决的是分布式数据库数据强一致性问题 , 实际应用中更多的是用来解决事务操作的原子性 , 下图描绘了协调者与参与者的状态转换 。
文章插图
站在协调者的角度 , 在发起投票之后就进入了 WAIT 等待状态 , 等待所有参与者回复各自事务执行状态 , 并在收到所有参与者的回复后决策下一步是发送 commit提交 或 rollback回滚信息 。
站在参与者的角度 , 当回复完协调者的投票请求之后便进入 READY 状态(能够正常执行事务) , 接下去就是等待协调者最终的决策通知 , 一旦收到通知便可依据决策执行 commit 或 rollback 操作 。
两阶段提交协议原理简单、易于实现 , 但是缺点也是显而易见的 , 包含如下:
- 单点问题
- 同步阻塞
- 数据不一致性
针对上述问题可以引入 超时机制 和 互询机制在很大程度上予以解决 。
超时机制对于协调者来说如果在指定时间内没有收到所有参与者的应答 , 则可以自动退出 WAIT 状态 , 并向所有参与者发送 rollback 通知 。对于参与者来说如果位于 READY 状态 , 但是在指定时间内没有收到协调者的第二阶段通知 , 则不能武断地执行 rollback 操作 , 因为协调者可能发送的是 commit 通知 , 这个时候执行 rollback 就会导致数据不一致 。
互询机制此时 , 我们可以介入互询机制 , 让参与者 A 去询问其他参与者 B 的执行情况 。如果 B 执行了 rollback 或 commit 操作 , 则 A 可以大胆的与 B 执行相同的操作;如果 B 此时还没有到达 READY 状态 , 则可以推断出协调者发出的肯定是 rollback 通知;如果 B 同样位于 READY 状态 , 则 A 可以继续询问另外的参与者 。只有当所有的参与者都位于 READY 状态时 , 此时两阶段提交协议无法处理 , 将陷入长时间的阻塞状态 。
推荐阅读
- 一元一g一小时流量发什么给10086,10085打电话说流量-
- 等保2.0的解决方案,“零信任架构”SDP介绍
- 银行数据仓库的系统架构是什么?看这篇足矣
- 什么是微内核架构设计?
- 洋葱架构Onion Architecture
- 年轻人痴迷的互联网有多挣钱?架构师稳坐高薪榜首
- 为什么CTO、技术总监、架构师都不写代码,还这么牛逼?
- 基于SpringBoot的微服务架构与K8S容器部署实践
- 一通百通,一文实现灵活的 K8S 基础架构
- 微服务架构下该如何技术选型呢?