事务提供一种机制将活动中涉及所有操作纳入到一个不可分割的执行单元。整个单独单元作为一个不可分割的整体,如果单元中某条sql语句一旦执行失败或者产生错误,整个单元将会回滚,也就是所有受到影响的数据将会返回到事务开始以前的状态;如果单元中的所有sql语句均执行成功,则事务被顺利执行。
事务的属性
在系统当中,包含了库存和订单两个独立的服务,每个服务维护了自己的数据库。
在发生交易时,我们购买商品,先调用库存服务,减库存,再调用订单服务,创建订单。
正常情况下,两个数据库都更新成功,两边数据维持着一致性。
但是,也会出现非正常情况,如减库存完成后,创建订单失败,这时导致两边数据不一致。
在不同的服务怎么保证大家都成功呢? 分布式事务。
分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。
CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。
CAP原则的精髓就是要么AP,要么CP,要么AC,但是不存在CAP。
BASE 理论是对 CAP 中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。
二阶段提交(Two-phaseCommit),强一致性解决方案;
两个阶段:准备阶段和提交阶段。
准备阶段
协调者节点向所有参与者节点询问是否可以执行提交操作(vote),并开始等待各参与者节点的响应。各参与者节点响应协调者节点发起的询问。如果参与者节点的事务操作实际执行成功,则它返回一个”同意”消息;如果参与者节点的事务操作实际执行失败,则它返回一个”中止”消息。
提交阶段
如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。(注意:必须在最后阶段释放锁资源)。
方案总结:
2PC 方案实现起来非常简单,但是会带来以下问题:
三阶段提交协议,是二阶段提交协议的改进版本,与二阶段提交不同的是,引入超时机制。同时在协调者和参与者中都引入超时机制。
三阶段提交将二阶段的准备阶段拆分为2个阶段,插入了一个preCommit阶段,使得原先在二阶段提交中,参与者在准备之后,由于协调者发生崩溃或错误,而导致参与者处于无法知晓是否提交或者中止的“不确定状态”所产生的可能相当长的延时的问题得以解决。
三个阶段:CanCommit阶段、PreCommit阶段、doCommit阶段。
CanCommit阶段
协调者向参与者发送commit请求,参与者如果可以提交就返回yes响应(参与者不执行事务操作),否则返回no响应。
PreCommit阶段
协调者根据阶段1 canCommit参与者的反应情况来决定是否可以基于事务的preCommit操作。如果CanCommit阶段所有参与者均反馈yes,所有参与者预执行事务;如果CanCommit阶段任何一个参与者反馈no,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务。
doCommit阶段
该阶段进行真正的事务提交。PreCommit阶段所有参与者均反馈ack响应,执行真正的事务提交。如果任何一个参与者反馈no,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务。
方案总结:
优点:相比二阶段提交,三阶段贴近降低了阻塞范围,PreCommit阶段在等待超时后协调者或参与者会中断事务。避免了协调者单点问题,doCommit阶段中协调者出现问题时,参与者会继续提交事务。
缺点:数据不一致问题依然存在,当在参与者收到preCommit请求后等待do commite指令时,此时如果协调者请求中断事务,而协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。
TCC是服务化的二阶段编程模型,最终一致性,其Try、Confirm、Cancel 3个方法均由业务编码实现;
TCC事务的Try、Confirm、Cancel可以理解为SQL事务中的Lock、Commit、Rollback。
Try 阶段
这个阶段主要完成所有业务检查( 一致性 )、预留必须业务资源( 准隔离性 );
Try 尝试执行业务 TCC事务机制以初步操作(Try)为中心的,确认操作(Confirm)和取消操作(Cancel)都是围绕初步操作(Try)而展开。因此,Try阶段中的操作,其保障性是最好的,即使失败,仍然有取消操作(Cancel)可以将其执行结果撤销。
Confirm / Cancel 阶段
根据Try阶段服务是否全部正常执行,继续执行确认操作(Confirm)或取消操作(Cancel)。 Confirm和Cancel操作满足幂等性,如果Confirm或Cancel操作执行失败,将会不断重试直到执行完成。(重试机制+幂等特性)
方案总结:
TCC事务机制相对于传统事务机制(X/Open XA),TCC事务机制相比于上面介绍的XA事务机制,有以下优点:
缺点: TCC的Try、Confirm和Cancel操作功能要按具体业务来实现,业务耦合度较高,提高了开发成本。
本地消息表的方案最初是由ebay提出,此方案的核心是将需要分布式处理的任务通过消息日志的方式来异步执行。消息日志可以存储到本地文本、数据库或消息队列,再通过业务规则自动或人工发起重试。人工重试更多的是应用于支付场景,通过对账系统对事后问题的处理。
Saga事务 ,最终一致性,核心思想是将一个长事务拆分为多个本地短事务来处理。
Saga二种恢复策略:
Saga事务常见的实现方式:
方案总结:
命令协调优点和缺点
事件编排的优点和缺点
本文介绍了分布式事务的一些特性和解决方案,结合自己的项目实际情况,看看比较适合哪一种,是侧重强一致性还是最终一致性。