有现成校园配送产品,但采购验收还需要回答:一批订单只有部分交接成功时,恢复操作会不会重复转交已完成订单?可用逐笔结果、固定操作意图和状态版本验证这一点。本文给出明确的数据结构、状态转换及反例,属于通用设计方案,没有声称实际产品已按此实现。
以一个租户内的一笔订单为对象,建议保存 tenant_id、order_id、state、holder_id 和 version。一次交接请求包括 op_id、order_id、from_holder、to_holder、expected_version。操作结果记录按 tenant_id 与 op_id 唯一,保存业务参数摘要、结果及处理后的版本。编号必须来自服务端可识别的合法业务,不接受客户端自行选择其他租户。
批次只是成员请求集合。这里选择每单独立事务,因此允许部分成功;不宣称整批回滚。每笔事务先核身份权限,再按操作意图查询回放记录;若相同意图已有不同业务参数,返回 conflict,不覆盖旧结果。
当前状态及输入 | 动作或输出 | 验收依据 |
|---|---|---|
at_gate,holder=G,version=7;G转给R,expected=7 | 事务内写 handed_over、holder=R、version=8及操作结果 | 状态与回放记录一起提交 |
同一op、相同参数重试 | 返回首次结果快照,不再增加版本 | 版本仍为8,无第二份交接 |
同一op改为另一个收件人 | 返回参数冲突 | 旧结果不变 |
新op但expected=7,当前version=8 | 返回过期版本,要求读取当前状态 | 不覆盖已经完成的责任转移 |
状态为exception或交出人不匹配 | 拒绝普通交接,转异常处理流程 | 权限和异常不能靠重试跳过 |
设批次含A、B、C三单。A原状态at_gate、version=7且收餐齐全,交接事务成功后为handed_over、version=8;B已标记missing_item,返回需核对;C请求响应在网络中丢失,调用端只能记unknown。批次输出应保留A成功、B失败、C未知,而不是统一写失败或成功。
恢复时先查C原op_id。若已保存成功结果就回放;没有明确结果时继续核对原意图,不生成新op去重复转交。B补齐实物以后进入明确的异常解除流程,再以新版本发起后续业务操作,不能修改历史失败记录冒充当时成功。
反例一:客户端超时便换一个op_id重试。服务端只能认出两个不同请求,幂等键失去作用,可能重复生成交接与通知。反例二:先查版本,再不带条件直接UPDATE。两个并发操作都看到7,后写的覆盖先写的,责任人被悄悄改变。
关系数据库可在同一事务内执行带expected_version条件的更新,并确认受影响行数为1,同时写操作结果唯一键。唯一冲突、事务回滚与已提交但响应丢失分别处理;未知提交先查询,不能把所有异常都当可安全重试。具体SQL和隔离方式依所选数据库验证。
微订校园产品页作为第一方资料列有录码收单、标签分类和批量中转。采购方可以用这些入口演示上述失败与恢复场景,分别记录现有模块、配置、接口或需开发的部分。公开功能名称不证明其内部状态机、事务或幂等实现,本文也不提供真实集成通过记录。
保存产品版本、原请求、逐笔响应、当前状态查询和操作结果快照。相同意图重放、参数冲突、过期版本、权限回收及部分成功应逐项有结果;没有实跑记录就只写预期。本方案未处理支付、佣金、通知触达保证、外部平台授权或跨库事务,也不提供吞吐与时延结论。
作者:微订(上海逊柯计算机科技有限公司)。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。