H3.10.2no auto-retry for non-idempotent actions设计研究
非幂等操作不得自动重试
别名: 幂等 · 重复提交 · non-idempotent retry
概念解释
一次请求若每多发一次就会多产生一份副作用——扣款、发信、下单、让计数加一——它就不是幂等的。非幂等不得自动重试:超时不等于失败,自动再发可能把一笔变成两笔。恢复应先查询状态,再决定是补发、放弃还是让人挑。这条管「能不能自动再来一次」,不管重试几次封顶。
机制
超时切断的是观察,不是对端的执行。客户端以为没成功,对端可能已经做完。自动重试在观察层补一枪,执行层就可能再跑一遍。幂等键、去重窗口、先查询再决定,是把「再试」从再执行改成再对齐。没有这些,自动重试是在用用户的钱和收件人的收件箱赌网络是对称的。人可以在知情后选择再点一次,那是显式同意的第二次副作用;机器不能替他们同意。
怎么研究
对「扣一次积分」这类任务注入「实际已成功但客户端超时」,比较自动重试与先查询。
自变量:操作是否带幂等键、超时后是自动再发还是查询、查询失败时的默认。 因变量:重复副作用次数、用户以为失败但实际已成功的比例、第二次是否被拦住。
不要在实验室里用真钱。用可计数的副作用(发到实验邮箱的信、积分)并在对端日志里对账。
边界
真正幂等的读请求、覆盖式保存(后写覆盖前写且无额外副作用)可以自动重试。看似保存、实则「每次保存追加一条历史」的接口不是幂等。部分成功的批量里,已成功项不得随失败项一起自动再发。查询本身失败时,默认应是「状态未知」而不是再执行。
怎么落地
- 给支付、发送、创建类请求分类:无幂等保证的,客户端超时只进入查询或「查看结果」,禁止自动再 POST。
- 能加幂等键的,键由客户端在人点那一次生成,重试携带同一键,对端去重。
- 未知状态的文案写「可能已完成,请先查看」,动作是查看不是再来一次。
- 验证:让对端成功但故意不回包,看客户端是否又打出第二次副作用。打出了,这条路径就在自动重试非幂等。