---
author: "wx(GIT)"
schema: "hl-changelog/v2"
ticket: "5336"
title: "修改派单 requestId 持久幂等：同键重放冻结结果、不同载荷 605059"
consumer: "admin"
change_type: "修改接口"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "verified"
frontend_owner: "Pi"
frontend_ref: "hl-admin@49f38c7cfb4d5859a13c6ab1a7fea540cb524de5"
target_release: "v2.1"
verified_at: "2026-08-04"
status_note: "PR #5427 已 squash 合并到 dev-v3@d4243a2f6；测试部署任务 111419d8 双实例健康；网关真实 change 验证首次 200、同键同载荷重放冻结结果、同键异载荷 605059；管理后台已由 Pi 领取并开始适配。"
updated_at: "2026-08-04"
base: "dev-v3"
---


# 修改派单 requestId 持久幂等：同键重放冻结结果、不同载荷 605059

> **服务**：`hl-fleet-service`
>
> **Issue**：[#5336](https://git.1814.love:8443/wx/HL/issues/5336)
>
> **影响范围**：管理后台「修改派单」接口的幂等语义与错误码

---

## ⚠️ 关键变化

- 以前：`change` 接口对 `requestId` 只有 Redis 10 秒快速防重；TTL 到期后**同一 requestId + 相同 payload 重放会再次执行改派**（取消旧切片、生成新 group/assignment ID 与生命周期副作用）。
- 现在：`(operationType=CHANGE, requestId)` 在数据库持久唯一；成功后同键同 payload 重放**直接返回首次冻结结果，不再产生任何改派副作用**；同键不同 payload 返回 `605059`。
- 前端/调用方以前以为的重放安全不再成立，**重试安全成为持久承诺**；任何新 `requestId` 的合法再次改派不受影响。

## 变更接口

| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 修改派单 | POST | `/admin/fleet/assignments/:assignmentId/change` | 错误码与幂等语义 | 无请求/响应字段变化 |

## 变更详情

### 3.1 幂等语义（行为变化）

- 请求体字段（含 `requestId`）与响应字段**均不变**。
- 首次成功后，相同 `requestId` + 相同业务载荷（规范化后）重放：返回首次冻结的完整响应（同 `assignmentId/assignmentSlotId/newAssignmentGroupId/...` 等），**不**生成新的 group/assignment、OperationLog、Outbox 或生命周期 intent。
- Redis 10 秒快速防重仍保留，仅承担首次并发抑制，不再承担业务正确性；DB 唯一回执跨 TTL 兜底。
- 同 `requestId` + 不同业务载荷：稳定失败，返回：

| code | 含义 |
|---|---|
| `605059` | 幂等请求标识已用于不同业务载荷 |

- `requestId` 大小写精确区分；首尾空白或超过 64 字符返回参数错误。
- 新 `requestId` 的再次合法改派不受阻，正常形成新业务变更。

## 前端消费动作

1. 正常业务无需改动；重试逻辑可依赖持久幂等（同键同载荷重复提交不再重复改派）。
2. 若收到 `605059`，说明同一 `requestId` 被用于不同内容，必须更换新 `requestId` 重新提交，不得原地重试。
3. 前端双击/重放场景：响应内容与首次一致，无需重新拉取详情。

## 验证证据

- Fleet H2 集成：`AssignmentChangeReceiptServiceIntegrationTest` 8/8、迁移测试 2/2。
- 真实 MySQL 8.0.33 + Redis + Spring AOP：`AssignmentChangeReceiptMysqlTest` 1/1（含跨 TTL 并发 exactly-once）。
- `AssignmentServiceTest` 340/340；Fleet 全量 verify 结果以 PR 合入后工单回写为准。
- oasdiff 与 Spring Cloud Contract 未配置，不能标记工具 PASS；以上为源码级字段对比与集成测试回退证据。

## Internal Feign / shared Java

无内部 Feign 或共享 Java 契约变化。

## 关联 / 联系人

### 链接

- **Issue**: [#5336](https://git.1814.love:8443/wx/HL/issues/5336)
- **PR**: [#5427](https://git.1814.love:8443/wx/HL/pulls/5427)
- **Merge commit**: [d4243a2f65eb](https://git.1814.love:8443/wx/HL/commit/d4243a2f65eb)
### 联系人

- **后端负责人**: @wx
