## Context 批量订购逐行调用后台订单创建,并在全部行处理结束后于同一事务保存任务结果和完成审计。当前完成审计以关联订单审计事件数量充当成功行数;该数量会包含失败记录和重试记录,可能大于输入总行数,违反审计表的批量统计约束并回滚任务完成状态。 ## Goals / Non-Goals **Goals:** - 使任务完成审计使用本次处理结果的业务成功数和失败数。 - 保持任务结果、汇总计数和完成审计在同一事务提交。 **Non-Goals:** - 不改变单笔订单、钱包余额不足或重复输入的业务规则。 - 不恢复或重放历史任务;历史数据由维护者按生产运维流程处置。 ## Decisions - 以 `processRows` 返回的 `successCount` 和 `failCount` 作为任务完成审计的唯一批量统计来源。这些值与将写入任务记录的逐行结果来自同一次处理,满足审计表的计数不变量。 - 移除对关联订单审计事件数量的查询。审计事件数量会因失败记录和重试而膨胀,不能表示批量业务成功数。 ## Risks / Trade-offs - [历史待处理任务不自动恢复] → 保持现有状态,避免对已扣款订单重复执行;由维护者核对后受控结案。 - [完成审计仍依赖事务写入成功] → 使用与任务结果一致的统计值,消除本次约束失败原因,同时保留既有原子性。 ## Migration Plan 1. 发布 API/Worker 中的修复后二进制,重点更新 Worker。 2. 在隔离环境验证部分成功任务返回完成状态与一致计数。 3. 生产历史任务由维护者在核对订单和源文件后手工结案;不重投原 Asynq 消息。 4. 若发布异常,回滚 Worker 二进制;该修复不含迁移。