POST /orders
一把锁挡住此刻,
一把锁挡住此刻,
一条记录记住结果
连续点击并不可怕,真正危险的是服务端把每次重试都当成一笔新订单。调整请求身份,再观察状态机如何决定“继续处理、复用响应,还是拒绝冲突”。
锁只覆盖很短的执行窗口;幂等记录要活得足够久,才能让晚到几秒甚至几分钟的网关重试仍然得到同一个业务结果。
POST
/orders · user-1042 · idem-checkout-7f3asku=RDS-01 · quantity=1 · ¥199.00
REQ #000
未创建
处理中
已成功
可重试失败
参数冲突
—
等待发起请求
先建立第一笔订单。之后改变用户、幂等键或请求体,观察服务端到底是在识别同一次业务意图,还是接受一笔新业务。
{
"state": "EMPTY"
}
Server contract
服务端的判定顺序
- 用
userId + Idempotency-Key定位记录,不能只拿客户端键做全局 key。 - 记录存在时先比对请求摘要;摘要不同立即返回
409 Conflict。 - 状态是
PROCESSING时返回202 Accepted,提示客户端稍后轮询或重试。 - 状态是
SUCCEEDED时原样复用首次201响应,不再创建订单。 - 只有未创建或明确标记为可重试失败,才尝试获取短锁并执行订单事务。
事件记录
新的事件显示在最上方- 00:00.000READY尚无 Redis 记录,数据库中也没有本次练习创建的订单。