唯一索引拦截重复提交(MongoDB 示例)
唯一索引拦截重复提交(MongoDB 示例)
// 每个业务请求带一个幂等键(客户端生成或网关下发)
db.idempotency.createIndex({ key: 1 }, { unique: true })
try {
db.idempotency.insertOne({ key: "req-8f2c", createdAt: new Date() })
// 首次请求:继续执行业务
} catch (e) {
if (e.code === 11000) {
// 重复请求:查询首次结果直接返回,或告知处理中
} else {
throw e
}
}
// 清理:给幂等键设 TTL,覆盖业务允许的重试窗口即可| upsert | 按主键写入最新状态:重复执行结果一致(ReplacingMergeTree、ES 同 _id 覆盖同理) |
|---|---|
| 版本条件 | 带版本更新(CAS):旧版本重放不生效,防止覆盖新状态 |
| 去重表 | 记录已处理事件 ID,与业务写入同事务提交才能保证不漏不重 |
幂等窗口要覆盖该接口的重试与重放周期:窗口过短,晚到的重试会重复执行;窗口过长,去重表占用增大。