关键事实

Future.await 点可能被取消。若状态更新分布在多个 await 之间,就可能出现“写了一半”的业务状态。

设计原则

  1. 把副作用集中在单一提交点。
  2. 在可取消区间只做纯计算或幂等准备。
  3. 对外部系统写入使用幂等键。

反例与修正

// 反例:先扣库存再写订单,两个 await 中间可被取消
reserve_stock().await?;
create_order().await?;

// 修正:准备阶段无副作用,最后一次性提交
let plan = build_plan().await?;
commit(plan).await?;

工程策略

  • 为关键流程增加“中断注入测试”。
  • 对每个 await 标注取消后的状态语义。
  • 引入补偿任务清理孤儿状态。

小结

异步取消是默认行为,不是异常路径。把 cancellation safety 当作接口契约的一部分,才能避免线上出现“偶发且不可复现”的脏状态。