TCC事务解析

1、场景说明

背景:

​ 分布式环境下,为保证事务一致性,通常采用两种算法:

  1. 二阶段提交

    • 实现方式
      • 锁定资源 - (确认占用 or 撤销占用)
      • try - (confirm or cancel)
      • 加锁A/预操作A - 加锁B/预操作B(确认A、B均能正确执行) - 提交(确认 or 取消)A/B操作 - 释放锁A/B
    • 存在问题(TCC为例)
      • 不能保证confirm、cancel一定都成功
        • 需要补偿机制
      • try阶段占用资源粒度不能过大,否则影响性能
        • 依业务而定,一般都可以缩小粒度到people 或者 product
        • 上面这条可以无视,我觉着程序员没有傻子
      • try阶段占用资源。如果不能及时confirm or cancel,会影响一致性。
        • 依业务而定,评估业务链条时间消耗,给出超时时间、补偿触发时间
        • 过早触发补偿,导致任务进行中就被撤销,业务成功率低。
        • 过晚触发补偿,导致资源长期占用,数据不一致。
  2. 三阶段提交

    1. 解决的问题

      • 二阶段提交,不能保证原子性
    2. 实现方式

      • 一阶段:

        • 发送消息到参与者
        • 确认是否能执行(一般为资源申请)
          • 是:进入阶段二
          • 否:中断操作
      • 二阶段

        • 发送消息到参与者
        • 预执行,记录undo,redo日志
        • 异常:参与者接不到协调者请求
          • 引发协调者超时
        • 异常-协调者超时:协调者接不到ACK响应,或者未全部接到
          • 发送abort给参与者
          • 中断事务

      • 三阶段

        • 提交事务

          • 参与者收到信号,提交
          • ==参与者未收到信号==,超时自动提交
    3. 存在问题:

      1. 确认提交时,协调者宣布abort,但是参与者未收到

        • 二阶段提交中,导致事务状态暂停———解决——记录协调者对事务的处理状态,做补偿机制
        • 三阶段提交中,导致参与者错误的提交请求———-解决——–同上———-
      2. 协调者故障

        • 协调者集群
        • 频繁失败,检测自身与各参与者网络连通性。从而将问题机器下线

2、TCC实战

  1. 常见流程
    1. 发起事务T,记录GLOBAL ID
    2. 调用服务A try,为服务A创建子事务,加入事务T
    3. 调用服务B try,为服务B创建子事务,加入事务T
    4. 根据服务调用结果,判定事务T,宣布confirm 或者cancel
    5. 服务A、B执行T宣布的结果
  2. 发起者本地事务
    1. 远程事务放在本地事务内,本地事务异常时,同步cancel远程事务
    2. 远程事务放在本地事务外,本地事务也当做远程事务处理
  3. 事务嵌套与事务传播
    1. 开启新事务,隔离
    2. 加入原有事务
  4. 补偿机制
    1. 超时时间设置
    2. 补偿次数
    3. 补偿间隔
    4. 防止并发
  5. 故障恢复
    1. 查找未完结事务
    2. confirm 或者 cancel