From 3699f4833c5f8eb5f1d66ed6cd3d1c1330daced8 Mon Sep 17 00:00:00 2001 From: oyo Date: Wed, 22 Oct 2025 17:21:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20knowledge.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- knowledge.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/knowledge.md b/knowledge.md index 7e33b2a..fe85a63 100644 --- a/knowledge.md +++ b/knowledge.md @@ -1704,5 +1704,62 @@ TOCO严格遵照分层规则,必须严格遵守,否则会产生严重后果 处理先读后更新场景时,为避免并发导致数据脏写,应充分利用BoService校验功能。例如:账户扣钱场景,避免并发扣除导致余额不足,传统raw sql用 `update account set balance = balance - amount where user_id = xxx and balance > amount` 的where条件保护;在TOCO中,应该:1、写方案中使用incr字段。2、在boService中添加保护代码 `if(userBo.getBalance() >= 0)` 或通过userBo业务不变性(聚合校验)添加 `balance>=0` 校验。 +#### 4.3 聚合校验识别与实现指南 + +##### 1. 业务不变性规则的明确判断标准 + +**必须放在聚合校验中的场景(四个核心判断标准):** + +✅ **标准1:聚合内实体间的约束关系** +- 父子实体之间的数据一致性约束 +- 示例:订单总金额 = 所有订单项金额之和 +- 示例:会议时间范围必须包含所有议程时间 +- 示例:主实体状态变更影响子实体状态的规则 + +✅ **标准2:聚合内集合类型字段的内部约束** +- 列表元素之间的互斥、重叠、顺序等约束 +- 示例:同一会议的议程时间不能重叠 +- 示例:同一用户的多个手机号不能重复 +- 示例:优先级序号必须连续且唯一 + +✅ **标准3:聚合根实体自身的完整性约束** +- 单个实体内多个字段之间的逻辑关系 +- 示例:开始时间 < 结束时间 +- 示例:折扣价 ≤ 原价 +- 示例:最小值 ≤ 最大值 + +✅ **标准4:领域概念的强制性规则** +- 体现核心业务概念的必然约束 +- 示例:会议必须至少有一个议程 +- 示例:订单必须至少有一个订单项 +- 示例:员工必须属于某个部门 + +**不应放在聚合校验中的场景:** + +❌ **场景1:需要外部数据查询的校验** +- 需要查询数据库其他表的数据 +- 需要调用其他服务的RPC +- 示例:会议室占用校验(需要查询其他会议) +- 示例:用户名唯一性校验(需要查询用户表) +- **实现位置**:Controller或Service层 + +❌ **场景2:用例特定的前置条件校验** +- 仅在特定API或业务流程中需要的校验 +- 非领域模型核心规则 +- 示例:必填参数校验 +- 示例:参数格式校验 +- **实现位置**:Controller层 + +❌ **场景3:需要重型操作的校验** +- 需要复杂计算或外部服务调用 +- 会严重影响性能的校验 +- **实现位置**:Service层 + +##### 2. 实现注意事项 +- 聚合校验方法会在写方案执行数据库操作前自动调用 +- 禁止在业务代码中显式调用validateAggregate()或valid()方法 +- 如果校验逻辑需要查询数据库或调用RPC,不要放在聚合校验中 +- 聚合校验应该是纯内存操作,执行速度快 + -----------------------------------------------------------------------------