I3.05.1retry under uncertainty设计
网络不确定时用户必然重试
别名: 不确定重试 · 再点一次 · at-least-once user · 超时重试
概念解释
请求发出去,应答迟迟不来:可能已经成功、可能还在路上、可能丢了。人无法分辨这三种,于是再做一次。这不是误操作,是网络不确定下的理性策略——至少一次(at-least-once)的用户行为。产品若按「每个人只会点一次」来建账,账一定会被点两次的人打乱。
这条解释的是重试为何必然发生。按钮先禁用、服务端如何识别两次为一次,是后面的手段,不是这条的原因。
机制
一次远程写入在用户眼里是一个动作,在系统里是「发出去」和「知道结果」两拍。中间的空白是不确定窗口。窗口里,屏幕若仍是可点的完成态之前的样子,模型是「没生效」;若转圈但没有结论,模型是「也许生效了,也许没有」。两种模型都把第二次动作标成合理:前者补做,后者确认。人不会为了保护服务器而忍受「钱可能扣了也可能没扣」。
超时、错误页、应用被杀、系统提示「无网络」再恢复,都会把同一意图再送一次。重试通道也不止按钮:下拉刷新、回车、操作系统的「恢复网页」、支付 SDK 的自动再扣。所以「用户必然重试」是统计事实,不是对某个控件的预测。设计对象是重复的意图,不是重复的点击。
边界
只读请求被重试,通常没有业务伤害,这条的压力小。本地瞬时反馈已经闭合因果(开关翻面不靠网络)时,人较少为同一意图再点,但若随后的服务器结果一直不来,仍会在设置页再拨一次。专业操盘、票务黄牛会把重试当工具,频率远高于普通用户,不能用实验室里的「点两次」当上限。明确的失败(「余额不足」「无权限」)把不确定关掉,人不会用同一参数再试,而会改参数或放弃;这时再来的第二次是新意图,不是这条里的重试。
怎么落地
- 把超时、杀进程、从后台回来都当成「同一意图可能再来一次」的触发源,而不是只防双击。
- 在不确定窗口里不要给出「可以当作没发生」的空屏;给出「仍在提交,请勿重复支付」还不够——要假定人仍会再试。
- 用同一意图的标识把多次到达收成一次,而不是教育用户「请不要再点」。
- 验证:点提交后立刻把网络切到丢包,等超时。统计有多少人会再点、下拉或重进页面。不为零就是必然。再用脚本在超时后把同一请求重放一次:若产生两笔订单、两封邮件、两次扣款,产品把不确定当成了只发生一次。