背景

Future 被丢弃时会清理局部资源,但已经发生的外部副作用不会自动撤销。在 await 前后修改共享状态,需要考虑中途取消。

核心判断

  1. 识别每个 await 点之前已经提交的状态与外部动作。
  2. 尽量先在锁外完成准备,再在短临界区内校验版本并提交。
  3. 不允许中断的业务由受监督任务持有,仍要设计超时与恢复。

最小示例

下面保留核心逻辑;业务类型、调用入口和环境配置按项目补齐。

// 准备在锁外执行;锁内只校验和提交,不跨远程 await。
let next = prepare(input).await?;
let mut guard = lock.lock().await;
if guard.revision != expected_revision {
    return Err(Error::Conflict);
}
apply(&mut guard, next);
guard.revision += 1;

边界与误区

不要拿着共享锁等待远程 I/O。示例的 prepare、lock、expected_revision 与状态对象是业务定义;版本检查失败需要重新评估,而非盲目覆盖。

验证方式

在各 await 点取消请求,确认共享状态不出现半提交。涉及付款或消息发送时,测试重试与核对机制能恢复已发生的外部动作。

小结

先在锁外完成可取消的准备,锁内校验版本并一次性提交状态,外部副作用另做幂等与核对。