空回滚就是对于一个分布式事务,在没有调用 TCC 资源 Try 方法的情况下,调用了二阶段的 Cancel 方法,Cancel 方法需要识别出这是一个空回滚,然 后直接返回成功。
解决方案:
1、try阶段逻辑开始的时候写入到 redis/mysql/其他 一条记录,状态为0;
try阶段逻辑结尾的时候更新记录状态为1;
2、cancel阶段可以凭此记录判断,1是正常回滚,0是空回滚
悬挂就是对于一个分布式事务,其二阶段 Cancel 接口比 Try 接口先执行。因为允许空回滚 的原因,Cancel 接口认为 Try 接口没执行,空回滚直接返回成功,对于 Seata 框架来说,
认为分布式事务的二阶段接口已经执行成功,整个分布式事务就结束了。
解决方案:
其实跟空回滚反过来就行了,cancel阶段执行开始的时候插入一条记录标记cancel已经执行,那么try阶段的逻辑结尾判断记录是否存在,存在则不再执行cancel
幂等就是对于同一个分布式事务的同一个分支事务,重复去调用该分支事务的第二阶段接 口,因此,要求 TCC 的二阶段 Confirm 和 Cancel 接口保证幂等,不会重复使用或者释放资源。
解决方案:
confirm 和cancel阶段的开始时候都要判断一下二阶段是否已经有开始的,如果没有则才开始。二阶段执行的开始的时候插入一条状态记录即可。
总结:其实只要try,confirm、cancel三个执行的时候都分别插入记录,互相判断一下即可解决上面的问题