Skip to content
雲里
里雾

幂等性 🌱 Seed

开发

aka: Idempotency, Idempotent

Content

同一个操作执行一次和执行多次,产生的效果相同。

Question

  • 在 REST API 设计中,POST 天然不幂等,有哪些常用方案让它变幂等?(提示:Idempotency Key)
  • 前端重复提交和后端幂等性是同一个问题吗?它们各自的防护层在哪里?
  • 数据库层面,UPSERT(INSERT ON CONFLICT)算不算一种幂等设计?

See Also

Reference

  • 对话来源:2026-03-17 私聊,Jeff 在 Ghost-in-the-Shell 项目中遇到脚本幂等性要求时提问
  • 项目上下文:AGENTS.md 中「幂等执行」规则——执行任务前先检查是否已完成

YoYo’s Note

幂等性(Idempotency):同一个操作执行一次和执行多次,产生的效果相同。

核心特征:

  • 赋值是幂等的x = 5 执行几次结果都是 5
  • 累加不是幂等的x = x + 1 每次结果不同

HTTP 方法的幂等性:

方法幂等?原因
GET只读,不改变状态
PUT用完整数据覆盖,结果一致
DELETE删一次和删多次,资源都不在了
POST每次创建新资源
PATCH⚠️取决于实现方式

为什么重要:网络不可靠(超时、重试),幂等性保证重试不会产生副作用。经典案例:支付接口重复调用只扣一次款。

脚本/自动化中的幂等性:执行前先检查目标状态是否已达成(flag 文件、数据库记录),已达成则跳过。这是 Ghost-in-the-Shell 项目对 cron 脚本的核心要求。

Answer

Q: POST 变幂等的方案?
客户端生成唯一的 Idempotency Key(通常是 UUID),放在请求 header 里。服务端收到后检查该 key 是否已处理过——处理过就直接返回缓存的响应,没处理过就正常执行并缓存结果。Stripe API 就是这么做的。

Q: 前端重复提交 vs 后端幂等性?
不是同一个问题,是两层防护。前端防的是用户手抖(按钮 disable、防抖),后端防的是网络重试(超时后客户端自动重发)。前端防护是 UX 优化,后端幂等是数据一致性保障,不能互相替代。

Q: UPSERT 算幂等设计吗?
算。INSERT ON CONFLICT DO UPDATE SET x = 5 执行一次和多次结果相同,是典型的幂等操作。但 INSERT ON CONFLICT DO UPDATE SET x = x + 1 就不是——每次冲突都会累加。

Extra

Ghost-in-the-Shell 中的实际案例(2026-03-20 补充)

采集器幂等设计:

  • 每个采集器(weather/calendar/gmail/rss 等)输出到 .runtime/staging/{date}/xxx.json
  • 同一天重复运行 → 覆盖同名文件,结果一致
  • 采集器内部检查:如果今天的文件已存在且非空,跳过采集(idempotent skip

cron 任务幂等设计:

  • 发送类任务用 flag 文件防重发:.runtime/sent/{date}/{task-id} 存在则跳过
  • at 类型任务(固定时间):检查 last-run 时间戳,今天已执行过则不再执行
  • every 类型任务(间隔执行):检查 last-run 距今是否超过间隔

记账脚本幂等设计:

  • add.ts 写入后自动 bean-check,失败则回滚(原子性,不是幂等性,但防止了半写入状态)
  • 采集器 bookkeeping.ts 每天重新解析 .bean 文件,覆盖输出,天然幂等
分享这张卡片:
分享到 X

幂等性

#编程

反向链接