文章 573
评论 5
浏览 219616
分布式事务重试幂等控制:网络抖动导致重复扣款?业务流水号 + 状态机拦截!

分布式事务重试幂等控制:网络抖动导致重复扣款?业务流水号 + 状态机拦截!

公司的支付系统出了个大事故。一笔订单因为网络抖动,支付回调超时了,系统重试了扣款。结果扣了两笔——用户投诉,财务对账发现了差异,运营逐笔人工退款。查日志发现,不是网络不通,是"半通"——第一次扣款请求发出去了,银联处理成功了,但响应在回来的路上丢了。系统认为扣款失败,又发了一次。 这种"网络半通"是分布式系统里最危险的情况——操作已经执行了,但调用方不知道。不加重试怕丢,加多了怕重。今天聊聊怎么用业务流水号加状态机,让重试在"安全"的边界内进行。 问题的本质:操作不是天然幂等的 HTTP 的 POST 不是幂等的,数据库的 INSERT 不是幂等的,银行的扣款接口更不是幂等的。如果不做任何处理,同一个扣款请求发两次,钱就会扣两笔。 分布式系统里有太多场景需要重试——网络抖动、超时、服务暂时不可用。重试本身是合理的,问题在于你拿什么来判断"这次重试的请求,上一次有没有已经成功过了"。 答案就是业务流水号。不是数据库自增 ID,不是 UUID,而是一个由业务方生成、全链路唯一、可用来判断"这条请求我见没见过"的标识。 业务流水号:请求的唯一身份证 业务流水号的核心原则:由发起方生成,....

TCC 空回滚与悬挂处理:网络抖动导致 Try 未执行直接 Cancel?幂等控制防误操作!

TCC 空回滚与悬挂处理:网络抖动导致 Try 未执行直接 Cancel?幂等控制防误操作!

做过分布式事务开发的同学肯定都遇到过这个问题:TCC 模式下的空回滚和悬挂问题。简单来说就是:Try 方法还没执行,Cancel 方法就来了;或者 Try 执行失败,但 Cancel 还是被调用了。这些异常场景处理不好,会导致数据不一致。 我之前就遇到过这样一个案例:用户下单时库存扣减服务超时,TC(事务协调器)认为 Try 失败,触发 Cancel 回滚。但由于网络抖动,库存服务实际已经扣减成功了,只是响应超时。结果 Cancel 方法又执行了一次"回滚",把已经扣减的库存又加回去了,导致库存数据错误。 今天我们就来聊聊 TCC 空回滚与悬挂的处理方案,让你的分布式事务更加健壮。 TCC 模式基础回顾 1. TCC 三阶段流程 TCC(Try-Confirm-Cancel)模式: 阶段一:Try(预留资源) - 锁定相关资源 - 检查业务可行性 - 如果不可行,直接失败,不进入后续阶段 阶段二:Confirm(确认执行) - 真正执行业务操作 - 确认使用预留的资源 - 失败会不断重试,直到成功 阶段三:Cancel(取消回滚) - 释放预留的资源 - 回滚业务操作 - 失败也会不断....

服务端开发博客:后端架构、高并发、性能优化与微服务实战教程