分布式事务

解决方案

  1. 两阶段提交(2PC)
  2. 三阶段提交(3PC)
  3. 补偿事务(TCC=Try-Confirm-Cancel)
  4. 本地消息队列表(MQ)
  5. Sagas事务模型(最终一致性)

两阶段提交(2PC)

参考
角色: 参与者Participant,协调者Coordinator(不一定需要是第三方节点)
流程
阶段1:
precommit 协调者 (事务内容) -> all参与者 (yes or no)
发送本次事务内容,询问是否可以提交并等待答复;
参与者执行事务操作,记录undo、redolog,但不提交,返回yes or no代表是否执行成功。

阶段2:
docommit 协调者 (roll or commit)-> 参与者(ack)
分两种情况讨论。
all参与者返回 yes——
协调者发送commit请求,参与者执行本地事务,对协调者进行ack,完成事务。

any参与者返回 no——
协调者发送rollback请求,参与者执行本地回滚,对协调者进行ack,完成事务。

异常情况
一阶段:
tc等待ab超时,tc发出roll指令;
只要tc决定commit,任意参与节点不允许回滚。因为资源都已冻结完毕,日志也已记录,就算挂掉,重启后也能根据相应的日志修复状态。

二阶段:
ab等待tc超时,
若一阶段回复的是no,可进行roll;
若回复的是yes,会一直等待

缺点
阻塞情况:所有参与者在提交阶段处于同步阻塞状态,会导致性能瓶颈;
单点问题:协调者挂了后,参与者一直阻塞。
复杂度:实现复杂,牺牲了可用性,不适合高并发

优点
满足了强一致(但并非100%)

三阶段提交(3PC)

角色: 参与者Participant,协调者Coordinator(不一定需要是第三方节点)
流程
阶段1:
cancommit 协调者 (询问) -> all参与者 (yes or no)
发送本次事务内容,询问是否可以提交并等待答复;
参与者执行事务操作,记录undo、redolog,但不提交,返回yes or no代表是否执行成功。

阶段2:
precommit 协调者 (事务内容)-> all参与者(ack or no)
分两种情况讨论。
all参与者返回 yes——
协调者发送precommit请求,参与者执行本地事务,对协调者进行ack,完成事务。

any参与者返回 no——
协调者发送abort命令,参与者收到后中断事务。

阶段3:
docommit 协调者 (roll or commit)-> 参与者(ack)
分两种情况讨论。
all参与者返回 ack——
协调者发送docommit请求,参与者执行本地提交,对协调者进行ack,完成事务。

any参与者返回 no——
协调者发送rollback请求,参与者执行本地回滚,对协调者进行ack,完成事务。

缺点
阶段三协调者出现问题时,参与者超时后会自动提交事务,若此时协调者发送了abort指令没收到,会导致出现数据不一致

优点
减小了阻塞范围,阶段一二参与者超时时会自动中断,

补偿事务(TCC=Try-Confirm-Cancel)

image-20211020195806449
核心思想
针对每个操作,都注册一个与之对应的冻结、确认、撤销操作。
流程
Try 阶段主要是对业务系统做检测及资源预留。
Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默
认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。
Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。
缺点
编码实现复杂,需要具体业务实现,耦合度高,复用性差。
优点
锁定资源粒度可以自由控制;可以保证数据最终一致性;

saga事务模型

又称之为长时间运行的事务Long-running-transaction
核心思想
image-20211020200919812
将分布式系统中的长事务拆分为多个短事务(或本地事务),然后由saga工作流引擎进行调度执行,如果流程正常结束,事务运行成功;否则会按流程相反的顺序进行补偿操作,重新进行业务回滚。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注