柔性事务

简介

  • 柔性事务遵循BASE,针对大型分布式系统,牺牲强一致,获得高可用
  • 高可用=系统构建在多机=分布式系统->高性能

实现方式

TCC

  • Try阶段执行成功,则执行Confirm,否则执行Cancel。
  • 如果try成功,默认comfirm一定成功,可以通过重试实现。

两个阶段

  • Try阶段。
    • 完成业务检查(一致性),预留资源(准隔离性)。
  • Confirm阶段。
    • 提交业务,不做检查,只是用预留资源执行操作。
    • 需要幂等。
  • Cancel阶段。
    • 取消业务,归还预留资源。
    • 需要幂等。

对比XA

  • XA:
    • 强一致,整个过程一直持有资源锁。
    • 资源层面事务,对开发屏蔽。
  • TCC:
    • 最终一致,只预留资源不会一直持有锁。
    • 业务层面事务,未对开发屏蔽。

日志和补偿

  • 记录事务日志-事务状态和上下文。可以通过MQ或者DB记录。
    • MQ实现简单,一阶段执行效率高,整体吞吐量高。
    • DB运维简单,第二阶段更加主动,单个事务的执行效率高。
  • 异常时通过正向补偿或者反向补偿。

事务消息实现

  • 消息中间件记录了整个事务的状态。
  • 第一阶段:保证事务1执行、MQ投递消息、MQ消费消息同时成功或者失败。
  • 第二阶段:执行事务2。事务2执行失败的两个方案:
    • 重新消费MQ。较为简单。
    • 回滚事务1。
  • 柔性事务

数据库实现

  • 数据库记录整个事务状态。
  • 第一阶段:
    • 执行成功,更新事务状态为第一阶段已执行。
    • 执行失败,删除事务记录,整个事务失败。
  • 第二阶段:
    • 执行成功,删除事务记录,整个事务成功。
    • 执行失败,为了简化吞掉异常,事务伪成功
  • 补偿任务筛选超时事务,调用业务方check接口校验事务状态。
    • 校验已完成,删除事务记录,事务成功。
    • 校验未完成,重试第二阶段。
  • 二阶段和check接口需要保证幂等,防止二阶段执行成功但是删除事务状态失败,check之后二阶段重试。

可靠消息传递

  • 第一阶段。事务中先操作数据库,再发消息。
  • 第二阶段。消费消息执行。
    • 消息至少投递一次,可能重复,消费方幂等。如业务流水号的排重表、redis记录完成状态等。

无锁隔离事务

  • 避免事务回滚。不回滚也能满足业务要求。
    • 比如先写辅助表再写主表,读的时候先读主表再读辅助表。
  • 辅助业务变化明细表。如库存预减明细表,计算存储的时候考虑库存+明细表,避免对一条库存数据抢锁。
  • 乐观锁。版本号校验,不匹配重试。

参考