TCC事务解析
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,会影响一致性。
- 依业务而定,评估业务链条时间消耗,给出超时时间、补偿触发时间
- 过早触发补偿,导致任务进行中就被撤销,业务成功率低。
- 过晚触发补偿,导致资源长期占用,数据不一致。
- 不能保证confirm、cancel一定都成功
- 实现方式
三阶段提交
解决的问题
- 二阶段提交,不能保证原子性
实现方式
一阶段:
- 发送消息到参与者
- 确认是否能执行(一般为资源申请)
- 是:进入阶段二
- 否:中断操作
二阶段
- 发送消息到参与者
- 预执行,记录undo,redo日志
- 异常:参与者接不到协调者请求
- 引发协调者超时
- 异常-协调者超时:协调者接不到ACK响应,或者未全部接到
- 发送abort给参与者
- 中断事务
三阶段
提交事务
- 参与者收到信号,提交
- ==参与者未收到信号==,超时自动提交
存在问题:
确认提交时,协调者宣布abort,但是参与者未收到
- 二阶段提交中,导致事务状态暂停———解决——记录协调者对事务的处理状态,做补偿机制
- 三阶段提交中,导致参与者错误的提交请求———-解决——–同上———-
协调者故障
- 协调者集群
- 频繁失败,检测自身与各参与者网络连通性。从而将问题机器下线
2、TCC实战
- 常见流程
- 发起事务T,记录GLOBAL ID
- 调用服务A try,为服务A创建子事务,加入事务T
- 调用服务B try,为服务B创建子事务,加入事务T
- 根据服务调用结果,判定事务T,宣布confirm 或者cancel
- 服务A、B执行T宣布的结果
- 发起者本地事务
- 远程事务放在本地事务内,本地事务异常时,同步cancel远程事务
- 远程事务放在本地事务外,本地事务也当做远程事务处理
- 事务嵌套与事务传播
- 开启新事务,隔离
- 加入原有事务
- 补偿机制
- 超时时间设置
- 补偿次数
- 补偿间隔
- 防止并发
- 故障恢复
- 查找未完结事务
- confirm 或者 cancel