API 幂等性设计:唯一约束、事务与故障恢复

举报
云上小栈 发表于 2026/11/09 07:34:18 2026/11/09
【摘要】 从请求重试、数据库唯一约束和事务边界出发,说明接口幂等性的实现及故障验收。

先区分请求重试与业务重做

创建订单、提交支付或触发任务时,客户端超时并不代表服务端没有执行。若直接重试,同一个业务动作可能发生两次。接口幂等性解决的是重复请求产生重复副作用的问题,关键在于让相同业务意图携带同一个标识,而不是简单限制请求频率。

幂等键由调用方生成

客户端第一次提交前生成随机请求标识,放入 Idempotency-Key 请求头,并在重试时复用。一次新的业务提交才生成新键。服务端按用户、接口和幂等键共同确定记录范围,避免不同用户使用相同键时相互影响。还应保存规范化请求内容的摘要:同一键对应不同参数时返回明确的冲突错误,不能沿用旧结果。

让唯一约束负责并发竞争

以 PostgreSQL 为例,可以建立处理记录表,用唯一约束保证同一请求只有一个执行者。

CREATE TABLE api_idempotency (
  user_id bigint NOT NULL,
  operation text NOT NULL,
  idem_key text NOT NULL,
  request_hash text NOT NULL,
  state text NOT NULL,
  response_body jsonb,
  created_at timestamptz NOT NULL DEFAULT now(),
  UNIQUE (user_id, operation, idem_key)
);

处理请求时先尝试插入记录。若已存在,读取状态和参数摘要:完成态返回原业务结果,处理中按接口约定返回状态查询地址或可重试错误。不要采用先查询、没有再插入的无锁实现;两个并发请求可能同时查不到,随后都执行业务。

业务提交必须覆盖故障窗口

如果业务数据和幂等记录位于同一个数据库,应在同一事务内更新业务并保存最终结果。这样提交成功而响应丢失时,重试仍能读到结果。若事务之外还要调用支付平台或发送消息,仅有本地记录不够:外部调用也需要稳定业务号,消息可结合事务发件箱与消费者去重。跨系统的每个副作用都需要独立考虑重复执行。

两个容易遗漏的边界

第一个边界是处理中记录长期不结束。进程在写入状态后退出,会留下悬挂任务。需要执行租约、超时核查或恢复队列,并通过业务状态确认是否已完成,不能看到超时就盲目重跑。第二个边界是记录清理过早。缓存过期后旧请求再次到达,可能被当成新请求。保留期限应覆盖真实重试窗口;订单号、支付流水等长期业务唯一约束仍应保留。

用故障场景验收

至少测试相同键并发提交、同键不同参数、事务提交后断开连接、处理中进程退出,以及过期后重复请求。检查最终业务记录数与外部副作用次数,不能只看 HTTP 状态码。幂等键、数据库唯一约束、事务和外部系统业务号需要共同工作,才能让接口在重试与故障下保持可预测的行为。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。