文档修改
This commit is contained in:
@@ -267,7 +267,79 @@ Fonrey 优先采用“预签名上传 + 回执提交(commit)”两段式。
|
||||
|
||||
---
|
||||
|
||||
## 9. 与模块文档的衔接规则
|
||||
## 9. 乐观锁(Optimistic Locking)规范
|
||||
|
||||
### 9.1 适用场景
|
||||
|
||||
`properties`、`clients`、`complexes` 三张高竞争表的更新操作(`PUT`/`PATCH`)**MUST** 使用乐观锁并发控制,防止"后写覆盖先写"数据丢失。
|
||||
|
||||
### 9.2 请求规范
|
||||
|
||||
客户端发起更新时,MUST 在请求体中携带当前资源版本号:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"sale_price": 180,
|
||||
"version": 3
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 兼容说明:当前 Fonrey 为内部 Web / Electron 客户端,采用请求体传递 `version` 字段,无需 `If-Match` Header(避免 HTMX 额外配置复杂度)。未来若提供对外开放 REST API,可补充支持 `If-Match: <version>` Header 形式。
|
||||
|
||||
### 9.3 服务端执行规范
|
||||
|
||||
服务端执行 UPDATE 时 MUST 同时匹配 `version`,并将 `version` +1:
|
||||
|
||||
```sql
|
||||
UPDATE properties
|
||||
SET sale_price = :sale_price,
|
||||
version = version + 1,
|
||||
updated_at = NOW(),
|
||||
updated_by = :operator_id
|
||||
WHERE id = :id
|
||||
AND version = :client_version -- 乐观锁匹配
|
||||
AND deleted_at IS NULL;
|
||||
```
|
||||
|
||||
- 若受影响行数 **= 1**:更新成功,返回 `200`
|
||||
- 若受影响行数 **= 0**:抛 `ConflictError`,返回 `409` + code `*_VERSION_CONFLICT`
|
||||
|
||||
### 9.4 冲突响应规范
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": false,
|
||||
"error": "已被他人修改,请刷新重试",
|
||||
"code": "PROPERTY_VERSION_CONFLICT",
|
||||
"details": {
|
||||
"field": "version",
|
||||
"your_version": 3,
|
||||
"hint": "请重新获取最新数据后再提交"
|
||||
},
|
||||
"meta": {
|
||||
"request_id": "uuid",
|
||||
"timestamp": "2026-04-28T10:00:00+08:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- HTTP 状态码 MUST 为 `409`
|
||||
- `code` 格式:`<MODULE>_VERSION_CONFLICT`(如 `PROPERTY_VERSION_CONFLICT` / `CLIENT_VERSION_CONFLICT` / `COMPLEX_VERSION_CONFLICT`)
|
||||
- 前端 SHOULD 展示 Toast:**「已被他人修改,请刷新重试」**,并自动触发资源重新加载
|
||||
|
||||
### 9.5 Check List
|
||||
|
||||
- [ ] `version` 字段在 GET 响应中 MUST 返回(供后续 PUT/PATCH 携带)
|
||||
- [ ] 服务层 update 方法 MUST 校验受影响行数,0 行时抛 `ConflictError`
|
||||
- [ ] 前端表单 MUST 在隐藏域中保存 `version`,随 PUT/PATCH 提交
|
||||
- [ ] HTMX 场景:冲突时后端 MUST 返回 `HX-Trigger: {"toast:error":"已被他人修改,请刷新重试"}`
|
||||
- [ ] 测试 MUST 覆盖:并发两次更新同版本,第二次 MUST 返回 `409`
|
||||
|
||||
---
|
||||
|
||||
## 10. 与模块文档的衔接规则
|
||||
|
||||
- 各模块技术方案中的“四、API 设计原则”“六、关键 API 规范”“十二、错误码建议”必须引用本文件
|
||||
- 模块文档可补充模块特有 code 与字段,但不得与本规范冲突
|
||||
|
||||
Reference in New Issue
Block a user