TCC分布式事务七种异常情况

大家好,我是小趴菜,上篇文章我们了解了下TCC的5种编程模型,也知道了在try,confirm,cancel三个阶段都应该做什么事,今天我们来学习下在整个TCC模型过程中可能会出现的几种异常情况

TCC标准编程模型

异常一:try阶段异常

在try阶段异常之后,就会执行cancel阶段,此时cancel阶段是一定要保证成功的,如果cancel阶段没有执行成功,那么就要进行重试

异常二:cancel阶段异常

其实这个异常的处理方式和异常一是一样的,失败了就重试,如果一直重试失败,那么就要进行人工干预

异常三:confirm提交异常

try阶段成功了,那么confirm一定要成功,如果失败了,那么就要进行重试,重试多次还未成功,那么就要进行人工干预

但是这里重试要注意,因为在confirm阶段有二步数据库操作,如果扣冻结张三20元成功了,但是李四加20元失败了,这时候重试就要做判断,看张三扣减20元是否之前已经操作成功了,如果操作成功了,就不要再次进行扣减冻结的操作

异常四:本地事务与TCC事务冲突

在try阶段我们添加了一个本地事务,如果这时候try阶段异常,那么本地事务就会回滚,所以这时候冻结张三20元的操作就会回滚,也就不会被冻结。那么这时候try阶段异常了,就会执行cancel阶段进行回滚

在cancel阶段,我们会还张三冻结的20元,这时候如果cancel执行成功,那么张三的金额就会多出20元,就会造成数据的不一致,所以一般不要加本地事务

js 复制代码
@Transaction(rollback=Exception.class)
@Hmily(comfirmMethod="confirmMethod",cancelMethod="cancelMethod")
public void try() {
  //查询张三余额信息  
  Account account = accountMapper.selectByUserId(1);
  //冻结张三20元
  account.setDJAccount(20);
  accountMapper.updateById(account);
}

异常五:空回滚

为什么会有空回滚的异常呢? 比如我们在执行try阶段的时候,由于超时了,导致TCC就去执行cancel阶段了,但是这时候try阶段还没有执行,也就是try阶段还没有冻结张三20元,这时候就造成了空回滚。

这时候我们需要引入其它手段,比如增加一张日志表,在回滚的时候,判断一下这是事务有没有执行try阶段,也就是这个事务有没有执行过try阶段,如果没有就不要执行cancel阶段的操作了。

异常六:第二阶段重复提交

第二阶段包括confirm,cancel,为什么会有重复提交呢? 因为我们不能保证confirm阶段或者cancel阶段一定能成功,如果不成功那么我们就要进行重试,

举个例子,在confirm阶段有二步数据库操作,假设扣减张三冻结20元成功,但是李四加20元失败了,这时候我们就要进行重试,但是重试的时候我们扣减张三冻结的20元已经操作成功了,所以不需要再次扣减了,所以我们要做好类似去重的操作,之前操作成功的就不要再次进行操作了

异常七:防悬挂

cancel阶段比try阶段先执行,由于网络原因导致try阶段超时,这时候就会执行cancel阶段操作,等cancel阶段执行完了,这时候try才执行,虽然事务失败了,但是这个事务已经结束了,所以这时候的try方法一定不能执行

相关推荐
Assby4 小时前
从 Function Calling 到 MCP:理解 Agent 工具调用的底层通信机制
人工智能·后端
打字机v4 小时前
创建第一个spring-boot项目
后端
像我这样帅的人丶你还4 小时前
Java 后端详解(三):全局异常处理与 JPA 数据库映射
java·后端
前端Hardy4 小时前
又一个 AI 神器火了!
前端·javascript·后端
NE_STOP4 小时前
vibe Coding -- 小项目实战
java
PBitW5 小时前
GPT训练我的第二天,我表示不过如此!!!😕😕😕
前端·javascript·面试
神奇小汤圆5 小时前
面试被问烂的Java虚拟机调优,我用一个实战案例给你讲得明明白白
后端
kyriewen6 小时前
白宫直接给 OpenAI 下了限制令,GPT-5.6 不能随便放出来了
前端·javascript·面试
明月_清风6 小时前
开发者网络概念全扫盲:一篇搞定
后端·网络协议
明月_清风6 小时前
零信任入门:从"城堡护城河"到"每次进门都要刷卡"
后端