微服务架构下分布式事务处理方案选择和对比( 二 )


两阶段提交协议仅仅是提供了分布式事务中的原子性属性,保证一个事务在全局要么全部提交,要么全部回滚,但是在并发控制上(隔离性),仍然需要封锁协议,为了达到分布式环境下全局串行和避免一个事务的失败可能引起一连串事务的回滚,通常使用强两阶段封锁协议(SS2PL) 。
两阶段封锁协议并不保证不会发生死锁,数据库系统必须采取其他的措施,预防和解决死锁问题 。但常见的数据库系统通常都实现了隔离级别,不同的隔离级别对于不同的锁机制,下表列出他们的对应关系 。值得一提的是,两阶段封锁协议并不保证不会发生死锁,数据库系统必须采取其他的措施,预防和解决死锁问题 。所以说,如果两阶段提交协议中事务时间越长,那么锁等待的时间和死锁的概率也会变大 。
弱一致性-事务补偿模型

微服务架构下分布式事务处理方案选择和对比

文章插图
 
事务补偿机制是指在事务链中的任何一个正向事务操作,都必须存在一个完全符合回滚规则的可逆事务 。例如存款操作通过取款操作来补偿、买入通过卖出来补偿 。
工作方式和限制
 
这里的“补偿”与数据库事务中的“回滚”是有区别的,“回滚”是指操作的取消,“回滚”前后对外界来讲,数据是一致的 。而“补偿”则是独立的逆向操作,如果事务执行了“补偿操作”,外界可能会看到数据的两种状态 。从这个角度讲,“回滚”需要锁定资源 。从数据库操作上来“补偿操作”其实也是一次短事务 。而“回滚”是一个事务内的操作 。
事务补偿通常在实现时采取嵌套事务的方式,即把一个主事务拆分成多个从业务操作,事务的发起和结束由主事务完成 。从业务服务提供的业务操作提供补偿操作,补偿操作可以抵销(或部分抵销)正向业务操作的业务结果 。业务活动管理器控制业务活动的一致性,它登记业务活动中的操作,并在业务活动取消时调用补偿操作 。具体回滚整个事务还是回退到某个事务点,可以依据具体业务来处理 。
在上面方式中可以看到需要手工编写大量的代码来处理以保证事务的完整性,我们可以考虑实现一个通用的事务管理器,实现事务链和事务上下文的管理 。对于事务链上的任何一个服务正向和逆向操作均在事务管理和协同器上注册,由事务管理器接管所有的事务补偿和回滚操作 。
补偿机制能正确工作是基于事务是可以补偿这一前提,如果这一前提无法满足,那么就无法使用这一机制 。现实业务场景中,确实存在这样的业务,例如证券交易,因为对时效性特别敏感,不能简单地使用卖出(买入)来补偿买入(卖出),因为不同时间交易的价格可能差距很大 。
另外,补偿操作也是一次事务操作,考虑到补偿操作也是有可能失败的,所以,补偿操作应该支持重试,这就要求补偿操作满足幂等性 。即重复调用多次产生的业务结果与调用一次产生的业务结果相同 。
事务补偿场景举例
在前面已经强调了,对于事务补偿必须满足幂等性要求,而且不能对时效性太敏感 。
场景:采购订单在提交时候调用预算检查和扣减,但是如果单据保存失败需要再次调用预算检查和调整,将扣减预算退回 。
那么基于以上场景事务补偿的核心实现逻辑如下:
微服务架构下分布式事务处理方案选择和对比

文章插图
 
  • 正常情况,调用预算扣减服务后,保存采购订单,两者需要同时成功
  • 如果调用采购订单保存服务出现失败,那么就需要对已经扣减的预算进行补偿和返还
  • 即调用和扣减预算完全对等的一个逆向操作,将扣减服务造成的影响全部回退
以上即是对事务补偿机制的关键说明 。
BASE最终一致性-可靠消息队列CAP理论概述
微服务架构下分布式事务处理方案选择和对比

文章插图
 
由于对系统或者数据进行了拆分,我们的系统不再是单机系统,而是分布式系统,针对分布式系统的CAP原理包含如下三个元素 。