一项能力能否长期维护,不取决于演示是否成功,而取决于团队能否解释每个状态、每次重试和每一份残留数据。 删除是长流程而非一个 SQL。先把实体标记不可访问并写 deletionId,再通过 outbox 向各处理者传播;tombstone 防止迟到事件复活。
数据设计需要同时说明原子写入、并发读写、版本迁移、崩溃恢复和清理策略。能成功保存一次不代表断电、空间不足或旧版本重开时仍保持一致。
设计时必须回答的问题
实现之前先列出不可违反的不变量,再为性能与体验留出调节参数。参数可以灰度,身份、权限和终态规则不能在运行时随意漂移。
- 每个处理者报告 deletionId、范围和 completedAt,协调器按保留矩阵等待或升级;失败可重试且不会重新读取已删除 payload。
- 为状态写出唯一所有者、版本号和终态;任何回调只能修改自己创建的版本。
- 上线参数必须有保守默认值、服务端上限和灰度开关,不能把浏览器传来的数字直接当作资源预算。
“删除请求的分布式传播:主库删了,缓存和对象还在怎么办”的交付标准是正常路径可用、异常路径收敛、资源有界,并且用户能理解系统为何采用当前状态。 这样得到的不是演示代码,而是能解释、能降级、能回滚的生产能力。
边界情况不是附加项
失败路径需要与成功路径共享同一套状态模型。只弹一个错误提示却不释放资源、不传播终态,下一次恢复就会继承脏状态。
- 物理删除主行后才发事件会失去定位下游对象所需键;缓存 TTL 很长时仅等待自然过期不满足用户承诺。
- 刷新或网络切换同时触发两条恢复路径,重复副作用被误当成两次真实用户操作。
- 指标标签直接包含用户或任务标识,既制造高基数成本,也让诊断数据泄露不必要的身份信息。
用证据确认它真的可用
验证需要先写预期状态轨迹,再执行故障注入。每个阶段同时核对用户可见结果、两端协议状态、持久记录和资源计数,才能证明闭环成立。
- 建立跨所有副本的 canary,删除时暂停一个消费者并注入旧更新事件,恢复后 canary 必须不可读且完成证据齐全。
- 让刷新、取消、超时和远端完成在同一调度窗口发生,断言系统只产生一个终态和一次副作用。
- 分别覆盖直连、中转、弱网、后台标签页和移动端,报告不能只给平均值或一次成功截图。
完成并不等于主路径跑通,而是每个终态都能对账、每个自动动作都受用户意图约束、每个成本都有明确上限。