I3.09.2stacked optimistic rollback scope设计

连续多个乐观操作叠加后,某一步失败的回滚范围需要明确边界

别名: 叠加回滚 · 回滚半径 · rollback radius · 多步乐观

概念解释

人连着做了几件乐观的事:先改标题,再加标签,再发一条评论。中间某一步被拒绝,回滚该掀掉哪几件?回滚范围(rollback scope)是事先说清的边界:只撤回这一步、撤回依赖它的后续步、还是整串都倒。范围含糊时,界面会掀错层——没失败的评论跟着消失,或失败的标题留着、后面建在错误标题上的标签还在。

这条不讨论单步回滚要不要干净,那是安放问题。这里是多步之间的半径

机制

每一步乐观都在上一步的结果上开新分支。步骤之间有依赖:评论「回复刚才那句」依赖那句还在;标签「加到这篇」依赖这篇的身份还在。一步失败,依赖它的后续步在真实世界上没有地基,继续显示它们等于把后续也变成谎言。反过来,与失败步正交的步(改的是另一条记录)被连坐,是把一次拒绝扩大成误伤。

范围因此不是「全部回滚」或「全部保留」的口味,是依赖图上的闭包。产品必须有一张图,即使图很浅:同一对象上的后续写入依赖,跨对象不依赖。没有图,实现往往用「时间上在失败之后的都倒」——这把正交操作也 sweep 进去——或「只倒这一条字段」,把建在失败结果上的后续留成幽灵。

边界

完全独立的乐观(给三封不同邮件标星)一步失败不应碰另外两封。向导式多步若每步都已向服务器提交,失败步之后的步可能已经在对端生效,回滚半径会被服务器拒绝:「后面的已经成真,不能只在屏幕上倒」。这时范围要改口为「屏幕回到失败步,并标明后续步在对端的命运」,而不是假装整串能倒。协同里别人基于你乐观过的标题开始写正文,你的标题回滚会变成别人的冲突,半径跨出了你的会话。批量「全选后归档」是一步,不是 N 步叠加;其中若干封失败是批量部分失败,用的是另一套范围(哪些条目),不要套用步骤闭包。

怎么落地

  • 给连续乐观建依赖:后续步声明自己依赖哪一次未确认写入。失败时只回滚该写入及其依赖闭包。
  • 在界面上让人能看出这一次回滚带走了哪几件(「标题未保存,已撤销基于该标题的两个标签」),不要只消失不计数。
  • 禁止用「失败之后发生的一切」当地图。正交操作要活下来。
  • 验证:乐观改标题、立刻乐观加两个标签、再乐观发评论。让「加标签」失败。标题和评论应仍在(若它们不依赖标签),两个标签应去掉。再让「改标题」失败:依赖标题文本的后续若存在应一起回滚;一条与标题无关的已发送评论不应消失。每次只失败一步,列出带走的对象,和依赖图对账。

延伸

  • 同组I3.09.1 回滚时机需要清晰地把界面带回失败前的状态而非留下过渡痕迹 · I3.09.3 回滚提示应说明失败原因与是否可重试,而非仅呈现内容消失 · I3.09.4 依赖乐观结果做出后续决策的操作需要在真实结果返回前保持谨慎
  • 相邻I3.02 乐观更新 · I3.13 状态机的完备性与非法状态
  • 站内检索rollback scope · stacked optimistic · dependency closure

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/I3.09.2