分布式事务研究

随着公司业务慢慢复杂中心化,跨系统的调用链条也越来越长, 任何一次的接口调用问题都会对业务的影响照成放大效应,本文旨在对分布式事务做一个小科普,欢迎各位大神批评指正。

 

什么是分布式事务?

分布式事务是指事务的参与者服务器、支持事务服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。

分布式事务现状

分布式事务实现受CAP理论(备注:一致性,可用性,分区容错性)制约,这决定分布式实现方式发展出两个方向XA(备注:遵守ACID)与BASE(备注:基本可用,柔性状态,最终一致性)。一种分布式事务并不能覆盖所有的业务场景,不同业务场合应该选择不同的分布式事务解决方案。

  • 强一致性事务。它通过数据库XA协议,第一阶段为准备提交事务阶段,等待所有资源准备就绪,第二阶段提交全局事务且保证数据强一致性。强一致性事务,性能比较差,适合对性能要求不高且数据一致性要求高的业务场景。(解决方案:本地事务ACID,分布式事务XA)
  • 柔性事务。它是通过补偿的方式,保证数据最终一致性。理论性能比较好,性能发挥到什么层度取决于设计者的设计方式,适合对强一致性要求不高,能接受数据延时,最终一致的业务场景。(解决方案:TCC,SAGA,正向消息补偿,反向补偿,其他自定义模式)

 

下面详细介绍分布式事务常用的5种协议:XA,TCC,SAGA,正向消息补偿,反向补偿

强一致性事务

一、XA协议

XA是由X/Open组织提出的分布式事务的规范。 XA规范主要定义了(全局)事务管理器(TM)和(局部)资源管理器(RM)之间的接口。主流的关系型数据库产品都是实现了XA接口的。(备注:TM:全局事务管理器,RM:单节点数据库)

  • 配置TM。把RM注册到TM。可以理解为给TM注册RM作为数据源。一个TM可以注册多个RM。
  • AP从TM获取RM节点管理权。
  • AP向TM发起一个全局事务。
  • AP操作RM,并且把操作RM的XID传递给RM,RM通过XID判断事务的关联性。
  • AP结束全局事务,并且TM通知RM全局事务结束。
  • 开始二阶段提交,全局事务TM发起事务提交。
  • 全局事务结束。

分布式事务研究

 

柔性事务

一、TCC协议

关于 TCC(Try-Confirm-Cancel)概念,由 Pat Helland 于2007年发表的一篇名为《Life beyond Distributed Transactions:an Apostate’s Opinion》的论文提出。

  • Try 阶段。尝试执行,完成所有业务检查的一致性检查,预留必需业务资源。
  • Confirm 阶段。真正执行业务,不作任何业务检查,只使用 Try 阶段预留的业务资源,Confirm 失败后需要进行重试。
  • Cancel 阶段。取消执行,释放 Try 阶段预留的业务资源。
  • Confirm阶段保证幂等性。即多次执行结果一致。

 

分布式事务研究

二、SAGA协议

关于 SAGA概念,由1987年普林斯顿大学的Hector Garcia-Molina和Kenneth Salem发表一篇为《Paper Sagas》的论文,讲述的是如何处理long lived transaction(长活事务)。Saga是一个长活事务可被分解成可以交错运行的子事务集合。其中每个子事务都是一个保持数据库一致性的真实事务。

  • Confirm 阶段。真正执行业务,不作任何业务检查,Confirm 失败后需要进行重试。
  • Cancel 阶段。取消执行。
  • Confirm-Cancel阶段保证幂等性。即多次执行结果一致。
  • 总结:Saga其实就是一个简化版本的TCC,其执行非异常场景执行步骤是N个sub-transation子事务,异常场景是2N个事务,TCC不管正常异常执行最少2N个事务,TCC适合处理有更多中间状态的场景,SAGA步骤少一种实现简单。

分布式事务研究

 

三、正向消息补偿(个人方案)

关于消息补偿方案,个人构思的一个方案,在程序方法做一个切面拦截请求方法,记录需要提供分布式事务的方法的入参,当方法执行正常的时候删除此条记录日志,当此方法异常的时候,触发重试对多次重试,对不通过的数据,邮件告警,目前本方案未开发。

  • 打标阶段。
    • 对需要执行分布式事务的方法打标记。
    • 通过aop切面拦截打标记的方法。
  • 请求链标记。
    • 每个请求链标记transId,全链路可以传递。(适配dubbo,spring boot,http链路)
    • 通过transId串起事务链。
  • 收集入参。
    • 对打标的方法收集其入参入库。
    • 方便后续做数据补偿的时候可以通过transId拿到入参。
  • 当正确执行。
    • 删除入参日志。
    • 销毁transId。
  • 异常执行。
    • 通过方法transId拿到入参
    • 通过反射调用异常方法进行重试
  • 全阶段保证方法幂等性。
  • ABA场景问题。比如updte db set x='小名' where id=1 这种场景。 此时,数据库被修改为x='小刚'。
    • 乐观锁解决法。 根据更新时间判断回滚数据是否有效,邮件通知人工处理异常。
    • 悲观锁解决办法。此方法使用分布式锁加select for update更新。(seate AT选择的解决方案)
    • 考虑性能问题,这种场景可以在用户端实现。

分布式事务研究

 

 

四、反向补偿

关于分布式反向补偿,其实是二阶提交概念的另外一种说法,目前业界的产品都是通过托管应用数据源,对需要处理分布式的方法生成反向的sql,如果方法执行失败,者执行反向sql恢复数据。

  • 反向补偿代表产品。 阿里seate AT模式

 

五、如何做到幂等

关于分布式补偿,最重要的就是幂等设计,如何做到幂等?可以从业务和技术两个方面保证。

  • 更新幂等。
    • 更新条件幂等性:我们写任何sql和方法要考虑前后执行一致性。比如:update set name=‘小刚’ where name=‘小明’就不是幂等的。
    • 更新时间幂等性:在做更新操作,防止久历史数据更新掉当前新数据。
  • 新增幂等。
    • 防止重复提交。新增场景,要做好防止重复提交
    • 唯一性ID校验。新增场景,需要加入唯一性ID校验。

 

 

自贩机分布式场景列举

 

下图列举,几类自贩机接口面临的分布式场景。

分布式事务研究

 

分布式事务产品

 

下图列举,目前市面上主流的分布式解决产品。

 

自研范围,补偿核心功能实现。

分布式事务研究

总结

个人对分布式事务的看法与总结

  • 分布式事务现状。 分布式事务受CAP理论制约,目前世界无完美解决方案。
  • 如何面对分布式事务。代码要巧妙设计能规避分布式事务就规避分布式事务。
  • 分布式事务与接口。产于分布式事务接口要全部设计成幂等性。
  • 分布式事务补偿框架实现 Cat源码Cat文档