依赖乐观结果做出后续决策的操作需要在真实结果返回前保持谨慎
别名: 乐观后决策 · 未确认就往下 · chain on optimistic · 过早承诺
概念解释
乐观结果一旦被当成真的,人会在它上面做下一件不可轻易收回的事:把「已发送」的消息转发给别人、用「已加入购物车」去结算、凭「已改好的权限」打开机密页。真实结果返回前保持谨慎指:后续决策要么等确认,要么被明确标成仍可收回,要么干脆在乐观窗口里不许做。
这和「不可逆操作不要乐观」不是同一刀。那里禁止把不可逆动作本身乐观掉;这里允许前面那步乐观,但禁止把未确认的结果当成后续动作的地基。
机制
乐观窗口里屏幕是真的、服务器可能是假的。后续决策把窗口里的值写进另一条因果链:转发引用了那条还可能被回滚的消息,结算引用了还可能没加进去的 SKU,导航引用了还可能被拒绝的权限。窗口闭合为失败时,回滚只能掀第一层;第二层已经跑到别人的收件箱、支付网关、或另一条路由。第二层没有对称回滚,于是出现「第一层倒了、第二层还在」的撕裂。
谨慎不是把产品冻住。它是把后续动作分成两类。一类读乐观值也无害(再点一次赞、再看一眼新标题)。一类会把乐观值输出到外部或不可收回处。第二类必须看见「未确认」这个门闩:按钮不可用、或可用但文案是「发送中,确认后再转发」、或转发本身被排队到确认之后。门闩是状态机上的守卫,不是文案装饰。
边界
纯展示的后续(根据乐观标题刷新导航栏文字)可以立刻变,回滚时一起变。用户自己心里做的决策(「我已经发了,去干别的」)拦不住,能拦的是产品提供的下一步入口。离线排队里,后续决策可以显式针对「待发送」而不是「已送达」——转发待发送应被拒绝或被标成「对方还收不到」。游戏或协作里以乐观位置做的本地预测(自己的角色先跑)是另一类,对端会纠正;那是预测,不是把未确认结果提交给支付。长时间确认(人工审核)会把谨慎窗口拉到分钟或天,后续动作更应默认锁住,而不是让人在审核期就把结果当完成来用。
怎么落地
- 标出所有「读取某次未确认写入」的后续入口:转发、结算、分享、授权后的跳转。未确认时禁用,或改为排队到确认后执行。
- 若必须可点,文案与状态要说「基于尚未确认的结果」,并在回滚时把后续动作一并停掉。
- 不要在乐观成功时就发出对外副作用(推送、邮件、webhook)。副作用跟权威确认走。
- 验证:乐观发送一条消息,在确认前点「转发」。若转发已到达第三方,而原消息随后回滚,撕裂成立。乐观加购后立刻结算:结算应等待加购确认,或在加购失败时自动退出结算并说明。权限乐观通过后打开机密页:权威拒绝时应立刻退出该页,而不是留在已经看过的内容里只把徽章改回去。