← ALL ARTICLES

场景补偿的版本承接

全库目录221
本文目录7

任务J在房间R中创建桌子T,移动A把T的局部X从0改为1,移动B再从1改为2。取消需要按B、A、创建的逆依赖顺序恢复,同时保留人工编辑。对象版本随每次写入单调增加;回到历史位置也会产生新版本。本文说明补偿如何承接这些版本。补偿期间的隔离与审核见补偿隔离与冲突接管。

补偿与版本恢复

创建暂存场景、放置资产、生成预览、导入验证和发布通常跨越多个工具。每步记录实际创建的ID与对应补偿:移除本操作创建的实例、释放临时资源或恢复发布指针。补偿也按操作ID幂等执行,且核对对象版本,避免删除后来被其他任务修改的内容。

每步成功后先保存实际结果与补偿参数,再派发依赖它的下一步。取消状态先置为Cancelling,使调度器停止新派发;对于已发请求逐项查询终态,迟到成功也登记到补偿列表。随后逆依赖顺序执行补偿,每项保存待补偿、已补偿或版本冲突。断电后继续相同列表,不能重新猜测哪些对象已经删除。

补偿操作也先登记独立的操作ID、原操作ID、预期当前版本和目标恢复状态。恢复变换与补偿标记在同一宿主提交中保存;响应丢失后先查询该标记,匹配便补记完成,不再用已经改变的对象版本判定冲突。删除则在场景清单保留带对象ID、原版本与补偿ID的墓碑;对象缺失而没有匹配墓碑时先对账,不能把任何一次删除都归为本次补偿成功。墓碑至少保留到任务恢复窗口结束,且所有可能重试的执行者已退出。

补偿坐标与父变换

任务的变换记录采用父局部空间。每项保存父ID与关系代次、输入局部矩阵、输出局部矩阵,以及计算时读取的祖先变换版本。执行接口需要世界矩阵时,宿主用同一快照的父世界矩阵P计算W=P×L;回执同时保存实际局部矩阵L与用于换算的P版本。位置使用米,矩阵乘法与引擎约定一致。父矩阵不可逆时拒绝需要世界到局部换算的操作,保持对象不变。

取消恢复的是本任务修改的局部字段。设R最初位于世界X=0,A将T局部X从0移到1,B从1移到2;人工再将R移到世界X=10,T自身版本仍为v3。撤销B的候选局部X为1,按当前R计算世界X=11。原世界X=1不是这次局部恢复的目标,写回它会把人工移动父对象的结果抵消。

父变换变化使原导航与净空结论失效。补偿器先取得新快照,构造候选局部恢复,按当前祖先和区域对象集合验证硬约束,并用匹配的导航版本生成布局诊断;导航未就绪记Pending。补偿读取集来自这次计算;原读取集保留为历史依据,不能直接替换其版本后沿用旧世界目标。宿主共同比较新读集、T的承接版本v3、父ID和关系代次,再提交局部X=1、新对象版本及补偿回执。

人工在检查后再次移动R时,提交返回DependencyChanged,场景不写入;调度器消费本次拒绝回执,重读并重算。

补偿链槽位保持不变,每次改变读取集合或目标都登记新的补偿尝试ID,载荷及摘要在该尝试内固定;响应未知时先查原尝试,只有确定拒绝或未接纳且已经关闭原提交权限,才建立下一尝试。原T版本已被外部修改则进入补偿冲突。

候选局部恢复违反宿主硬约束时进入CompensationConflict,报告规则与实际值;碰撞、净空和通路的中间诊断随补偿记录保存,按补偿隔离与冲突接管的隔离规则继续清理。审核可保留当前局部状态,或批准绑定当前快照的明确局部目标;宿主仍比较全部依赖。人工重挂父对象改变关系代次,自动恢复停在冲突,审核须明确选择保留新父关系还是恢复旧关系。场景工具的条件执行中的正向布局写入也采用这份局部契约,世界目标只作为宿主调用的派生值。

补偿回执保存空间、父关系、新读集、输入输出局部矩阵与版本。宿主已经恢复到世界X=11但响应丢失时,接管者先消费原回执承接游标;即使R随后移到20,也不会再次执行补偿把T拉回11。再次恢复仍读取同一补偿ID,后续撤销A则以最新快照独立计算局部X=0对应的世界目标。

连续移动的补偿承接

桌子最初处于版本v1。操作A把它移到靠墙位置,产生v2;操作B为通道再调整一次,产生v3。取消时先撤销B,把变换恢复到A完成后的值,但对象版本继续增加为v4。撤销A接下来必须检查v4;v2记录的是历史内容,不能当作此时的并发控制版本。

任务为每个对象保存正向操作链和补偿游标。链中每项包含前驱操作、输入版本、输出版本、修改字段及其原值;同一对象的正向写入按这条链串行完成。取消排空在途请求后,游标指向末项B,预期版本为v3。宿主在一次提交中比较v3,恢复B的原值,并保存补偿ID、输入v3、输出v4、下一待补偿项A和恢复内容摘要。该回执证明v4来自本任务撤销B,而非另一位编辑者。

调度器据持久回执把游标推进到A,预期版本设为v4。撤销A仍使用A登记的原变换,生成v5,再以相同方式推进。字段恢复之外的对象内容保持当前值;每一步检查整个对象版本,因而外部修改任何受版本管理的字段都会中止自动补偿。若人工在v4之后写出v5,撤销A以v4作条件比较便失败,即使人工恰好把桌子放回相同位置,也不会被误认为任务自身的恢复。

宿主提交成功而游标尚未更新就崩溃时,恢复先按补偿ID读取回执,再推进游标;游标更新和回执消费标记在登记数据库同一事务中完成。宿主侧回执随对象变化原子保存,不能仅由调度器在收到响应后补写。宿主不支持字段事务时,对象、版本与回执共同进入隔离场景快照提交。恢复者核对回执链的对象ID、任务ID和前驱补偿ID,只接受这条连续链上的输出版本,不能接受“来自同一任务”的任意版本。

创建操作也参与同一条链:家具的后续移动全部撤销后,创建补偿使用游标承接的最新版本删除家具,并保留删除墓碑。子对象存在冲突时,父对象的删除依赖尚未满足,任务停在CompensationConflict。

父子关系与跨对象版本

桌子挂入房间同时改变两份数据:T的父引用和R的子对象集合。本文把对象字段与关系分别版本化;对象版本保护变换、资产引用等字段,关系记录(关系ID, 父ID, 子ID, 关系代次)保护挂接,父对象另有单调递增的关系集合版本。创建桌子的一次宿主提交共同写入T、关系、R的新集合版本及操作回执;删除则共同写墓碑、删除关系、递增R的集合版本。跨房间移动也在同一提交中修改两边集合和T父引用。宿主以完整场景快照提交时,这些记录同属一个快照。

J创建R时得到对象版本r1、集合版本c0,挂入T后为c1。取消删除T得到c2;删除R接纳c2,需要删除T的持久回执证明c1到c2的变化属于当前补偿链。R自己的字段仍比较r1。任务维护每个受影响对象和关系集合的承接游标,一次跨对象回执列出全部输入、输出版本,调度器在同一登记事务中推进全部游标;不能只推进T而遗漏R。删除R还检查当前集合确实为空,集合版本匹配与空集合两个条件都成立才删除。

人工向R加入椅子会产生c3;即使J的桌子已删除,删除R比较c2仍失败。人工新增后又删除椅子会得到c4,集合虽空也不能跳过版本冲突。反过来,人工只改桌子的颜色会改变T对象版本,使删除T停止,关系继续存在,删除R的依赖保持阻塞。这样任务自身的清理可承接,外部改动仍留下明确冲突。

实现与证据

本页说明资产管线的设计协议与接口条件,未部署Agent、连接DCC、构建实际导航或执行资产发布。公式与数例可作机制推演,宿主事务、幂等性、恢复和发布仍需由各工具实现验证。事务边界的可运行示例见RPC。

相关主题

参考资料