手持机断网后,离线调拨该重试、查单,还是人工复核?
手持机上传一笔离线调拨时断网,恢复后仍显示失败。先查后台有没有与原操作匹配的回执或调拨单。有,就按后台确认的阶段往下处理。查不到,且接口支持同一操作幂等重放,才用原操作号和原内容重试。后台明确拒绝、回执对不上,或始终查不清,就保留原记录交给人工复核。
例如,仓管要把一台相机从器材库调到 B 房间。离线时手持机只来得及保存这条操作。后来他点上传,网络恰好在服务端写完记录后中断。这时屏幕上的「失败」描述的是客户端没有拿到结果。要判断相机能不能按新位置交接,还得区分三件事:操作已保存在设备上,调拨申请已在后台建单,调拨流程已完成。
复现一次「服务端写了,客户端没收到」
本次复跑沿用已发表文章附录中的 .NET 8 和 SQLite 示例,聚焦回执丢失后怎么对账。客户端和服务端各有一份数据库,通过本机 HTTP 通信。实验让服务端完成写入后主动断开响应,模拟弱网下回包丢失。退避时间用逻辑时钟推进。相机和房间均为合成数据。示例为便于观察直接更新位置,实际调拨还要经过业务流程。 原示例工程与运行说明
将原文附录的示例文件放到同一目录,安装 .NET 8 SDK,在 PowerShell 里执行:
.\run.ps1 -WorkRoot .\replay-001
使用新目录或空目录。如果本机已缓存示例依赖,可以追加 -Offline。运行结束后对照 run.stdout.txt 与 data/client.db、data/server.db。
同一个操作号 op-001 表示把 A-001 从 STORE-A 调到 ROOM-B。实验中始终用同一编号和同一份业务内容。
| 故障步骤 | 手持机侧模拟队列 | 服务端实测 | 恢复动作 |
|---|---|---|---|
| 请求返回 503,实验明确在写入前中断 | Unknown |
已受理 0 笔 | 退避后先查原回执。实验的回执接口返回未找到,才按原操作重试 |
| 重试时已写入,服务端在回包前断开连接 | 仍是 Unknown |
已受理 1 笔,位置变为 ROOM-B |
查同一操作号的原回执 |
| 查回原回执,操作号和目标房间匹配 | Done |
已受理仍是 1 笔 | 结束这条上传任务,不重建调拨 |
对照组 op-002 调拨一台当前不可用的资产 |
NeedsReview |
实验明确拒绝,未新增受理 | 留下原记录和拒绝原因,核对业务状态 |
查回回执时,写入接口的请求次数仍是 2 次,查回执本身只读。实验随后故意把 op-001 再发一次,拿到了重复回放标记,实际受理仍是 1 笔。最后直接读两份 SQLite:客户端一条 Done、一条 NeedsReview,服务端只有一条业务回执。对照资产仍在原房间。
这里最容易误判的是前两行。客户端看到的都是 Unknown,服务端一行没写,另一行已经写完。503 也只有在这个实验里能确定是写入前故障。线上看到 503、超时或断开时,应先保留「结果未知」,再按接口契约核对。
恢复网络后,三种结果怎么分
可以重试。 网络和原登录会话恢复,后台暂时没有可匹配的记录,接口也明确支持原请求的幂等重放,就在重试预算内沿用原操作号、设备和业务内容。若回执查询本身超时或被拒,继续保留未知状态。只有接口约定的「未找到」才能按未找到处理。对于普通业务 POST,能不能安全重试取决于服务端的业务语义,不能只看 HTTP 方法或状态码。参见 RFC 9110 第 9.2.2 节。
后台已经记单。 查到原操作对应的有效回执,或在后台核到同一资产、同一目标房间和同一笔调拨申请,就以这笔单据为准。若单据还在审批或执行中,手持机的上传任务可以结束,现场仍按流程处理。要确认资产已经归到目标房间,再核调拨完成状态和最新位置。仅看到资产目前在 B 房间,也不足以证明是这次操作把它调过去的。
需要人工复核。 后台明确提示已有未完流程、源房间与目标房间相同、资产编号无效,或无法把返回条目与原操作对上,就查看原操作和已有单据。网络恢复、权限核对和有限重试之后仍然查不清,也走这一分支。给接手人留下操作号、资产编号、目标房间、尝试时间、最后一次响应和已找到的单号。若要改目标房间,先确认原单如何处理,再发起新的业务意图。
用这三条去核 AssetaGuard 的调拨实现
以当前源码中按 EPC 逐项处理的手持机离线调拨分支为例。客户端用一组本地操作号计算批次幂等键,提交时带设备标识。服务端找到相同键和设备的历史记录,且能读出原结果时,会返回保存的逐项结果。首次创建成功的条目返回 created 和调拨单 ID。客户端按 EPC 对应每一项,匹配到 created 才把该操作记为上传成功。这里的成功指调拨申请已创建。
缺少该资产的逐项回执时,客户端走失败处理。已有未完流程的 pending_exists、源房间与目标房间相同的 ignored 走不可重试分支。若批次里还有其他资产,工程上还应注意:操作集合变了,按集合计算的批次键也可能变化。排查时先核已确认成功的条目和剩余失败条目,避免把整批重新录成新单。
上面的独立实验先调用只读回执接口;当前这条产品分支展示的是同键重放返回原逐项结果。对照实验的 Done、NeedsReview 是实验状态名。产品中实际可查的是同步报告、调拨单和资产位置。源码能说明实现分支,实机弱网下的页面行为还需要用对应设备和版本验收。
联调时可以挑一件测试资产,记录原操作号、设备和目标房间。让服务端在写入后断开一次响应,再恢复连接,用原请求核对回执和单号。最后分别核对上传任务、调拨单状态和资产位置。这个过程里,最有用的结果是能说清楚系统究竟停在哪一步,以及下一步该由手持机继续、由后台确认,还是由人接手。
- 点赞
- 收藏
- 关注作者
评论(0)