强一致性 - 图1

1 方案定义与优缺点

在任何时刻所有的用户或者进程查询到的都是最近一次成功更新的数据。强一致性是程度最高一致性要求,也是最难实现的。关系型数据库更新操作就是这个案例。

  • 优点:数据一致性高
  • 缺点:但是存在性能问题,在分布式事务未完全提交和回滚之前,查询不到新的数据,牺牲了可用性,实现也比较复杂,不适合高并发场景。

    2 模型

    2.1 DTP

    DTP中几个重要的概念,全局事务,分支事务
    全局事务:由事务管理器管理的事务,能够一次操作多个资源管理器
    分支事务:每个资源管理器中的独立事务
    image.png
    AP:应用程序
    RM:资源管理器,可以理解为数据库
    TM:事务管理器,负责协调和管理DTP模型中的事务,提供应用程序编程接口,同时管理资源管理器

    2.2 2PC

    2PC模型是指两阶段提交模型,它将事务流程分为prepare阶段和commit阶段。
    prepare阶段:事务管理器给参与全局事务的资源管理器发送prepare消息,资源管理器要么返回失败,要么在本地执行本地事务,将事务写入本地的redolog文件和undolog文件,此时事务并没有真正提交。
    commit阶段:事务管理器收到所有参与事务的资源管理器返回的消息来决定是进行全局事务提交或者回滚

image.png
2PC存在的问题
1.同步阻塞:事务执行过程,参与事务的节点都会对其占用的公共资源枷锁,导致其他访问受阻
2.单点故障:事务管理器发生故障,会导致资源一致阻塞
3.数据不一致:如果在commit阶段由于网络或部分资源管理器发生故障,会导致部分资源管理器未收到commit消息,导致数据不一致
4.无法解决的问题:如果如果commit阶段,事务管理器发出commit消息后宕机,并且唯一收到commit消息的资源管理器也宕机了,则无法确认事务是否已经提交

2.3 3PC

3PC是三阶段提交是2PC的改进版本,它将prepare分成了两个阶段多出了一个canCommit阶段,是否可以提交,再执行doCommit/doRollback。
image.png
阶段一
a) 协调者向所有参与者发出包含事务内容的 canCommit 请求,询问是否可以提交事务,并等待所有参与者答复。
b) 参与者收到 canCommit 请求后,如果认为可以执行事务操作,则反馈 yes 并进入预备状态,否则反馈 no。
阶段二
协调者根据参与者响应情况,有以下两种可能。
情况1:所有参与者均反馈 yes,协调者预执行事务
a) 协调者向所有参与者发出 preCommit 请求,进入准备阶段。
b) 参与者收到 preCommit 请求后,执行事务操作,将 undo 和 redo 信息记入事务日志中(但不提交事务)。
c) 各参与者向协调者反馈 ack 响应或 no 响应,并等待最终指令。
情况2:只要有一个参与者反馈 no,或者等待超时后协调者尚无法收到所有提供者的反馈,即中断事务
a) 协调者向所有参与者发出 abort 请求。
b) 无论收到协调者发出的 abort 请求,或者在等待协调者请求过程中出现超时,参与者均会中断事务。
阶段三
该阶段进行真正的事务提交,也可以分为以下两种情况。
情况 1:所有参与者均反馈 ack 响应,执行真正的事务提交
a) 如果协调者处于工作状态,则向所有参与者发出 do Commit 请求。
b) 参与者收到 do Commit 请求后,会正式执行事务提交,并释放整个事务期间占用的资源。
c) 各参与者向协调者反馈 ack 完成的消息。
d) 协调者收到所有参与者反馈的 ack 消息后,即完成事务提交。
情况2:只要有一个参与者反馈 no,或者等待超时后协调组尚无法收到所有提供者的反馈,即回滚事务。
a) 如果协调者处于工作状态,向所有参与者发出 rollback 请求。
b) 参与者使用阶段 1 中的 undo 信息执行回滚操作,并释放整个事务期间占用的资源。
c) 各参与者向协调组反馈 ack 完成的消息。
d) 协调组收到所有参与者反馈的 ack 消息后,即完成事务回滚。
优点:相比二阶段提交,三阶段提交降低了阻塞范围,在等待超时后协调者或参与者会中断事务。避免了协调者单点问题。阶段 3 中协调者出现问题时,参与者会继续提交事务。
缺点:数据不一致问题依然存在,当在参与者收到 preCommit 请求后等待 do commite 指令时,此时如果协调者请求中断事务,而协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。
3PC模型中资源管理器无法收到来自事务管理器发出的消息,资源管理会自己执行事务的提交,不会一致持有造成阻塞,但是这也会导致数据的不一致。
以上主要的问题还是会存在数据的不一致,如果解决这个问题。我们可以记录日志,每个分支事务执行流程中的状态信息。以供发生异常情况之后可以恢复事务。比如Atomikos框架。

引用资料

Mr.peter
https://www.cnblogs.com/peteremperor/p/13551408.html
白露非霜
https://www.cnblogs.com/nijunyang/p/15631443.html