状态、并发与一致性
从状态所有权和操作顺序解释原子性、版本、缓存失效、副本同步与冲突恢复。
先找到事实及其所有者
状态是系统在某个时刻保存、且会影响后续行为的信息。订单的付款状态影响是否发货;用户的显示偏好影响界面;缓存的商品价格影响计算。理解变化时,先说明哪个对象保存什么事实,谁可以改变它,其他参与者怎样取得它。
同一信息可以有权威记录、缓存、快照和派生值。权威记录承担决定结果的责任;缓存保存可重用的副本;快照保存某时刻的观察;派生值由其他事实计算。它们可以暂时不同,系统需要明确允许的差异和恢复方法。界面显示“已保存”应对应哪个确认点,也属于状态契约。
顺序怎样改变结果
两个参与者都读取数量 10,各自减 1,再写回 9。每一步计算都正确,组合结果却丢失一次变化。问题来自两次读改写共享了旧值。把完整操作串行化、使用原子更新或在提交时检查旧版本,都可以改变这段交错。
原子性说明某组变化在指定观察范围内作为整体成立或不成立;它必须带范围。单个进程的锁不会阻止另一进程修改数据库,一个存储事务也不会自动把外部邮件发送包含进去。并发控制要覆盖实际共享对象和所有写入者。
版本检查是一种乐观协调:读取对象及版本,提交时声明自己基于哪个版本。版本已经变化时拒绝或重算。锁是一种排他协调:取得访问许可后执行,其他参与者按规则等待。选择取决于争用、失败、持有时间和操作能否重试。
顺序、可见性和一致性
“先调用”可以指本地代码先后、网络发送先后、接收先后或提交先后。不同参与者不一定看见同一顺序。并发操作没有被已有因果关系排序时,系统需决定接受哪种结果,或提供冲突信息。
一致性描述参与者能观察到哪些状态及顺序。强的共同顺序便于判断,但协调可能增加等待和失败条件;允许暂时差异可以继续工作,同时要求传播、合并和恢复。不能只用“强一致”“最终一致”名称代替读写规则和具体承诺。
例如先写后读是否必须见到自己的修改,两个读者是否可以暂时见到不同版本,断网写入怎样处理,都是能直接检查的承诺。最终达到一致也需要传播完成、更新不再继续和适用的合并规则等条件。
缓存怎样有效,又怎样失效
缓存的结果由输入和观察条件决定。键应表达影响结果的参数、主体范围和版本。只以文章编号缓存受权限影响的响应,会让不同主体共享不适用的结果。缓存值还需要说明保存时间、有效期和依据。
写入后可以删除相关缓存、写入新值、发布失效事件,或让消费者在下次读取时验证。TTL 限定复用时间,没有保证写入后立即新鲜。并发读取也可能在失效之后把旧值重新填回,需要版本条件或其他协调。
HTTP 的新鲜度与验证是协议层的一种实现:有效期内可以按条件复用,过期后可用验证器询问表示是否变化。本页只借它辨认“有副本”和“仍有效”的区别,完整字段规则见协议实践。RFC 9111,HTTP 缓存
部署后的本地缓存还面对格式变化。构建版本标识、模式版本、迁移或丢弃旧缓存分别处理不同问题。服务数据仍有效,却可能无法由新客户端解析;因此内容新鲜度和表示兼容性需要分别管理。
副本怎样同步
副本同步先决定传播什么:当前状态、变更操作或事件。状态传播容易取得完整值,合并要识别版本;操作传播保留变化,但要处理重复、顺序和缺失;事件记录支持重建,仍需定义事件意义和消费者进度。
断网后本地修改可以保留待同步操作。重连时带上已知版本或进度,取得缺失信息,再合并。最后写入覆盖是一种明确政策,但可能丢失并发意图;字段级合并、人工裁决或特定数据类型能保留更多关系,代价随语义增加。
CRDT 为特定数据结构设计能合并的更新规则。成立条件取决于采用的状态型或操作型方案、传播和去重等规则。它能帮助副本收敛,业务权限、付款不变量和删除政策仍需另行建立。协作光标等 presence 通常是短暂状态,文档内容则需要不同的保留与恢复条件。
失败后如何知道发生了什么
恢复至少需要主要事实、版本或进度、待执行操作和明确的重复处理规则。只恢复界面缓存,不能证明所有本地修改都已上传。测试同步应包含交错、重复、乱序、断连和重连,观察最终状态及丢失的业务含义;一次正常连接无法证明收敛。
本文整合 TS 缓存、离线、实时、Yjs 协同与代码组织材料。持久化介质、数据库事务和具体浏览器存储由数据专题及实践展开,本文保留它们对状态协调的必要关系。
最后更新于