一文读懂分布式事务及其解决方案

文章目录

    • 一、什么是事务?
    • 二、什么是分布式事务?
    • 三、分布式系统的一致性
      • 1、CAP原则
      • 2、Base理论
    • 四、分布式事务的解决方案
      • 1、2PC
      • 2、3PC
      • 3、TCC
      • 4、本地消息表
      • 5、Saga
    • 五、总结

一、什么是事务?

   事务提供一种机制将活动中涉及所有操作纳入到一个不可分割的执行单元。整个单独单元作为一个不可分割的整体,如果单元中某条sql语句一旦执行失败或者产生错误,整个单元将会回滚,也就是所有受到影响的数据将会返回到事务开始以前的状态;如果单元中的所有sql语句均执行成功,则事务被顺利执行。

事务的属性

  • 原子性:一个事务不可在分割,要么都执行要么都不执行;
  • 一致性:一个事务的执行会使数据从一个一致状态切换到另一个一致的状态;
  • 隔离性:一个事务的执行不受其他事物的干扰;
  • 持久性: 一个事务一旦提交,则会永久的改变数据库的数据;

二、什么是分布式事务?

一文读懂分布式事务及其解决方案_第1张图片
在系统当中,包含了库存和订单两个独立的服务,每个服务维护了自己的数据库。
在发生交易时,我们购买商品,先调用库存服务,减库存,再调用订单服务,创建订单。
正常情况下,两个数据库都更新成功,两边数据维持着一致性。
但是,也会出现非正常情况,如减库存完成后,创建订单失败,这时导致两边数据不一致。

在不同的服务怎么保证大家都成功呢? 分布式事务。
   分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。

三、分布式系统的一致性

1、CAP原则

   CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。

  • 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
  • 可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
  • 分区容忍性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。

  CAP原则的精髓就是要么AP,要么CP,要么AC,但是不存在CAP。

2、Base理论

  BASE 理论是对 CAP 中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。

四、分布式事务的解决方案

1、2PC

  二阶段提交(Two-phaseCommit),强一致性解决方案;
  两个阶段:准备阶段和提交阶段。

  准备阶段
  协调者节点向所有参与者节点询问是否可以执行提交操作(vote),并开始等待各参与者节点的响应。各参与者节点响应协调者节点发起的询问。如果参与者节点的事务操作实际执行成功,则它返回一个”同意”消息;如果参与者节点的事务操作实际执行失败,则它返回一个”中止”消息。

  提交阶段
  如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。(注意:必须在最后阶段释放锁资源)。
一文读懂分布式事务及其解决方案_第2张图片
方案总结
  2PC 方案实现起来非常简单,但是会带来以下问题:

  • 性能问题:在提交阶段所有事务参与者处于同步阻塞状态,容易导致性能瓶颈
  • 可靠性:单点故障问题,一旦协调者宕机了,所有事务参与者将阻塞。
  • 数据一致性:部分事务参与者收到了commit消息,另一部分参与者没有收到commit消息,那么导致节点之间的数据不一致问题。

2、3PC

  三阶段提交协议,是二阶段提交协议的改进版本,与二阶段提交不同的是,引入超时机制。同时在协调者和参与者中都引入超时机制。
  三阶段提交将二阶段的准备阶段拆分为2个阶段,插入了一个preCommit阶段,使得原先在二阶段提交中,参与者在准备之后,由于协调者发生崩溃或错误,而导致参与者处于无法知晓是否提交或者中止的“不确定状态”所产生的可能相当长的延时的问题得以解决。
  三个阶段:CanCommit阶段、PreCommit阶段、doCommit阶段。
一文读懂分布式事务及其解决方案_第3张图片
CanCommit阶段
  协调者向参与者发送commit请求,参与者如果可以提交就返回yes响应(参与者不执行事务操作),否则返回no响应。

PreCommit阶段
  协调者根据阶段1 canCommit参与者的反应情况来决定是否可以基于事务的preCommit操作。如果CanCommit阶段所有参与者均反馈yes,所有参与者预执行事务;如果CanCommit阶段任何一个参与者反馈no,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务。

doCommit阶段
  该阶段进行真正的事务提交。PreCommit阶段所有参与者均反馈ack响应,执行真正的事务提交。如果任何一个参与者反馈no,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务。

方案总结:

  • 优点:相比二阶段提交,三阶段贴近降低了阻塞范围,PreCommit阶段在等待超时后协调者或参与者会中断事务。避免了协调者单点问题,doCommit阶段中协调者出现问题时,参与者会继续提交事务。

  • 缺点:数据不一致问题依然存在,当在参与者收到preCommit请求后等待do commite指令时,此时如果协调者请求中断事务,而协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致

3、TCC

  TCC是服务化的二阶段编程模型,最终一致性,其Try、Confirm、Cancel 3个方法均由业务编码实现;

  • Try操作作为一阶段,负责资源的检查和预留。
  • Confirm操作作为二阶段提交操作,执行真正的业务。
  • Cancel是预留资源的取消。

TCC事务的Try、Confirm、Cancel可以理解为SQL事务中的Lock、Commit、Rollback。
一文读懂分布式事务及其解决方案_第4张图片
Try 阶段
  这个阶段主要完成所有业务检查( 一致性 )、预留必须业务资源( 准隔离性 );
  Try 尝试执行业务 TCC事务机制以初步操作(Try)为中心的,确认操作(Confirm)和取消操作(Cancel)都是围绕初步操作(Try)而展开。因此,Try阶段中的操作,其保障性是最好的,即使失败,仍然有取消操作(Cancel)可以将其执行结果撤销。

Confirm / Cancel 阶段
  根据Try阶段服务是否全部正常执行,继续执行确认操作(Confirm)或取消操作(Cancel)。 Confirm和Cancel操作满足幂等性,如果Confirm或Cancel操作执行失败,将会不断重试直到执行完成。(重试机制+幂等特性)

方案总结:
  TCC事务机制相对于传统事务机制(X/Open XA),TCC事务机制相比于上面介绍的XA事务机制,有以下优点:

  • 性能提升:具体业务来实现控制资源锁的粒度变小,不会锁定整个资源。
  • 数据最终一致性:基于Confirm和Cancel的幂等性,保证事务最终完成确认或者取消,保证数据的一致性。
  • 可靠性:解决了XA协议的协调者单点故障问题,由主业务方发起并控制整个业务活动,业务活动管理器也变成多点,引入集群。

缺点: TCC的Try、Confirm和Cancel操作功能要按具体业务来实现,业务耦合度较高,提高了开发成本。

4、本地消息表

  本地消息表的方案最初是由ebay提出,此方案的核心是将需要分布式处理的任务通过消息日志的方式来异步执行。消息日志可以存储到本地文本、数据库或消息队列,再通过业务规则自动或人工发起重试。人工重试更多的是应用于支付场景,通过对账系统对事后问题的处理。

5、Saga

  Saga事务 ,最终一致性,核心思想是将一个长事务拆分为多个本地短事务来处理。

  • 每一个Saga事务都是由一系列的幂等有序的子事务(sub-transaction) Ti组成。
  • 每一个Ti都有对应一个幂等补偿动作Ci,补偿动作作用于撤销Ti执行的结果。

Saga二种恢复策略:

  • 向前恢复 (适用于必须要成功的场景):如果在执行过程中发现子事务出现错误,会一直重试知道成功为止,才会进行下一个事务执行。
  • 向后恢复(每一个操作都对应一个补偿操作):把前面执行成功事务进行撤销。
    一文读懂分布式事务及其解决方案_第5张图片

Saga事务常见的实现方式:

  • 命令协调: 中央协调器负责集中处理事件的决策和业务逻辑进行排序。
  • 事件编排: 没有协调器,也不会出现单点问题,每个服务产生并观察其他服务的世界,并决定是否执行自己的逻辑。

方案总结:

命令协调优点和缺点

  • 优点:服务之间关系简单,避免服务之间的依赖关系;程序开发简单,降低了参与者的复杂性;易于维护扩展
  • 缺点:协调器中的逻辑如果比较复杂,导致后期维护困难;存在单点故障问题。

事件编排的优点和缺点

  • 优点:不存在中央协调器,避免了单点故障问题;当涉及的步骤较少服务开发简单,容易实现。
  • 缺点:服务之间存在循环依赖的问题;服务步骤涉及比较多情况下,服务之间关系混乱,不易于调试。

五、总结

  本文介绍了分布式事务的一些特性和解决方案,结合自己的项目实际情况,看看比较适合哪一种,是侧重强一致性还是最终一致性。

你可能感兴趣的:(Java)