文章目录
一、TCC简介
在两阶段提交2PC(2PC,Two Phase Commitment Protocol)过程中,事务管理器和资源管理器是最大功臣
-
资源管理器功能是实现TCC功能,即try、Confirm、cancle三个操作。TCC是一种比较成熟的分布式事务解决方案,可用于解决跨数据库、跨服务业务操作的数据一致性问题;TCC被称为服务化的资源管理器。try:实现资源的检查和预留;confirm:真正的事务提交;cancle:二阶段事务回滚操作,释放预留资源,是资源回到原始状态。
-
事务管理器功能是协调所有资源管理器,执行‘prepare准备’和‘commit提交/rollback回滚’操作。事务管理器协调所有资源管理器统一执行一阶段try操作,同时询问所有资源管理器一阶段是否准备成功,如果所有资源管理器一阶段成功,那么事务管理器协调所有资源管理器二阶段执行Confirm提交操作,否则(其中一个资源管理器失败或者所有资源管理器失败),统一执行cancle回滚操作。
2PC事务管理器控制所有资源管理器最终一致性。
二、TCC设计
1、业务实现TCC
业务中的一条操作做成2PC两阶段,一阶段只实现资源的检查和预留;二阶段只实现事务的提交和回滚
举例场景:“账户A的余额中有100元,需要扣除其中30元”;
未使用TCC之前,编写SQL:“update 账户表 set 余额 = 余额 -20 where 账户 = A”,便能一步完成扣款操作;
使用TCC之后,就需要考虑如何将扣款操作分成2步完成:
-
try操作:资源的检查和预留;
在扣款场景,try操作要做的事情就是先检查A账户余额是否足够,再冻结要扣款的30元(预留资源);此阶段不会发生真正的扣款。 -
confirm操作:执行真正业务的提交;
在扣款场景下,confirm阶段走的事情就是发生真正的扣款,把A账户中已经冻结的30元钱扣掉; -
cancel操作:预留资源的释放,恢复原始的状态。
在扣款场景下,扣款取消,cancel操作执行的任务是释放try操作冻结的30元钱,是A账户回到初始状态。
2、并发控制
以下还是以A账户扣款为例,“账户 A 上有 100 元,事务 T1 要扣除其中的 30 元,事务 T2 也要扣除 30 元,出现并发”;
在一阶段try操作中,分布式事务T1和分布式事务T2分别冻结资金的那一部分资金,相互之间无干扰;这样在分布式事务的二阶段,无论T1是提交还是回滚,都不会对T2产生影响,这样T1和T2在同一笔业务数据上并行执行。
3、允许空回滚
空回滚:事务管理器在准备阶段协调所有资源管理器执行try操作的过程中发生网络抖动或者阻塞等原因,导致事务管理器超时发起事务回滚操作,TCC服务端应该允许该操作。回滚操作比准备操作先到TCC服务端,TCC服务端可执行该回滚操作叫做空回滚。
4、避免事务悬挂
事务悬挂:事务管理器发起准备操作,由于网络抖动或者阻塞等原因,导致事务管理器超时发起回滚操作,TCC在回滚之后,被阻塞的请求到达TCC服务端,迟到的准备操作导致TCC执行的try操作,而二阶段不会再执行提交或者回滚操作,导致try事务悬挂。
TCC服务端需要提供避免事务悬挂解决方案:被悬挂的事务被取消,不会再执行try操作
5、幂等控制
无论是网络数据包重传,还是异常事务的补偿执行,都会导致TCC服务的Try、Confirm或者Cancel操作被重复执行;用户在实现TCC服务时,需要考虑幂等控制,即Try、Confirm、Cancel 执行一次和执行多次的业务结果是一样的;
三、事务悬挂的解决方案
悬挂的事务被误提交会造成资损,解决方案如下:
1、 30秒内拒绝空回滚:某种程度上解决由于短时间网络阻塞导致的事务悬挂
2、误提交避免方案:
- 各条分支事务一阶段成功之后在TCC服务端保存事务id到列表,二阶段提交事务来临时先检查列表是否包含该事务id,如果包含,提交。
- TCC管理一个调用次数,进行约束:第一次调用,插入主事务记录;非第一次调用锁住事务记录。通过这个调用次数就能控制存在悬挂时不允许重新发起新事务。第一次预处理请求只允许insert主事务记录,非第一次预处理只允许select…for update主事务记录