二阶段提交的作用
二阶段提交是为了要保证分布式事务的原子性,理解这里的原子性:通过协调准备、执行两步操作,整个过程要么成功,要么失败回滚,对外部来说,该事务的状态变化是原子的。
二阶段提交的角色
概念解释比较抽象,边看边理解即可。
TC (Transaction Coordinator) - 事务协调者
维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
XA规范
是X/Open DTP定义的事务协调者 与 数据库 之间的接口规范,即 TC <--XA--> RM;事务些调整通过这个XA规范来通知数据库事务的开始、结束(提交/回滚)
XA规范的实现 由数据库厂商提供。
二阶段提交的工作流程
整个流程是TC和 多个RM之间的一个互动的过程,简单来说就是【预备->跑】 这样两个过程,即准备和执行两个阶段:
- 准备阶段:TC通知每个RM准备,RM开始执行分支事务,但是不提交,相关资源会被锁;每个RM给TC反馈已准备就绪,等待下一步的提交指令进行分支事务提交。
- 提交阶段:TC通知每个RM提交分支事务,RM完成分支事务提交后,释放资源并反馈TC;TC确认所有RM的分支事务完成后,流程结束
二阶段提交的角色解读
image.png- TM即其实整个事务的发起者,这个发起者内的逻辑决定了本次大事务覆盖的分支事务有哪些,其执行逻辑控制着整个大事务的开始、结束(提交/回滚)
- 由于每个RM(数据库)可以保证自己数据库中的分支事物,但不能保证除自己以外的其他RM(数据库)的分支事务,因此需要第三方(TC)介入协调;
- 理论上这个TC可以是由TM自己来兼职,但从职责边界的角度看,如果TC是独立的,那么TM和RM就会变得很轻巧,TC的功能也会更内聚,也更容易通过集群部署提升可用性。
二阶段提交的异常流程
image.pngTC通知每个RM准备,其中部分RM反馈准备阶段出错;或者TC在规定时间内没收到所有RM完成准备的反馈; TC要发起回滚通知每个RM。
因天然的存在网络和设备问题,会导致TC 和 RM 出现异常:
-
- TC异常:
- 1.1 TC发出【准备】指令前出问题,对RM无影响,因为RM都未开始事务,不占用RM的资源
- 1.2 TC发出【准备】指令后【提交】指令前,TC出问题,各RM开始执行事务并挂起等待下一步的提交指令,相关的资源会被锁定,其他的事务若要操作被锁定的资源也需等待;
- 1.3 TC发出【提交】指令后,TC出问题,若部分RM异常,那就出现了部分RM正常执行,部分RM未正常执行,即产生了数据不一致的问题。
-
- RM出问题
- 2.1 TC发出准备指令后,部分RM反馈准备阶段出错,或者TC在规定时间内没收到所有RM完成准备的反馈; TC要通知每个RM回滚。
- 2.2 TC发布提交指令后,部分RM出问题,那么也会产生数据的不一致问题
二阶段的缺陷
所有问题可以归为以下三种:
- 协调者故障:
需通过集群高可用来规避单机故障 - 性能问题(资源利用率低):
等待指令,如果遇到网络或节点问题,会导致长时间等待,处于挂起状态;需要通过增加超时自省机制,来限制挂起时间,并指定超时后的默认处理 - 数据不一致:
这个没有绝对的保证,只能尽量。通过【鸵鸟算法】了解更多。
三阶段提交协议
正常流程
- can commit: TC协调所有RM进行预检,预检过程不锁定资源
- pre commit:收到所有RM的can commit的正常反馈后,TC通知所有RM开启并执行事务但不提交事务
- do commit:收到所有RM的pre commit的正常反馈后,TC通知所有RM提交事务
关键设计
目标是通过引入以下逻辑来修复二阶段的缺陷:
- 引入预检环节,避免在不具备锁定资源的条件下锁定资源
- 在TC和RM中都引入超时机制,超时后自醒,主动执行自认为合理的下一步逻辑(回滚或者提交),避免无上限的挂起:
2.1 TC端,遇到超时就给RM发abort指令,中断整个事务
2.2 RM端,在收到can commit 后,pre commit之前,超时自醒后直接中断RM的分支事务
2.3 RM端,在收到pre commit 指令后,等待下一步的do commit指令超时,直接提交事务(大概率是正确的选择,但如果是错误的选择就导致了数据的不一致)
异常流程
1. can commit阶段:
- 部分RM直接反馈不能开始事务,TC向所有RM发送abort请求。
- TC等待反馈超时,TC向所有RM发送abort请求。
- RM预检没问题,但一直无法接收到下一步的的指令(反馈can commit超时 或接收TC 下一步指令超时),执行事务的中断
- RM收到来自TC的abort请求之后执行事务的中断;
2. pre commit阶段
- TC收到RM反馈异常,向所有RM发送abort请求,执行回滚
- TC等待反馈超时,向所有RM发送abort请求,执行回滚
3. do commit阶段
- RM收到pre commit指令并正常执行事务,给TC反馈pre commit完成后,理论上是要等待下一步的do commit指令后才提交事务;但是如果未能等到下一步的do commit指令超时了,会自主提交事务。因为经过预检通过,执行到这个阶段整个事务成功的概率已经很高了;
- 部分RM pre commit异常,部分RM pre commit 正常,但此时TC挂了,那么通过RM的超时自醒机制,就出现部分RM提交,部分RM回滚,出现数据不一致。
- 另外一种情况,TC发送了abort 指令,RM超时未收到指令就提交了事务,其他RM收到了TC发送的abort指令后执行了回滚,会出现数据不一致。
三阶段的优缺点
优点:通过预检,避免了资源的无效占用;TC端和RM端各自的超时自醒处理,避免长时间资源占用不释放。提高资源利用率
缺点:多出了一个流程,增加了复杂度;依然有数据不一致的问题
网友评论