面试题答案
一键面试CouchDB自带的冲突处理机制
- 版本控制:CouchDB使用MVCC(多版本并发控制),每个文档都有一个
_rev
(修订版本号)。每次文档更新,_rev
会变化。例如,初始文档_rev
为1-abcdef
,更新后可能变为2-ghijkl
。 - 冲突检测:当多个客户端同时更新同一文档时,CouchDB会检测到冲突。它会保留所有冲突版本,并将文档标记为有冲突状态。此时,文档的
_conflicts
字段会列出冲突的_rev
列表。 - 冲突解决:
- 手动解决:用户可通过CouchDB的API获取冲突版本,查看内容后手动选择保留哪个版本。比如通过
GET /{db}/{doc_id}?conflicts=true
获取带有冲突信息的文档。 - 自动解决:CouchDB默认使用最后写入获胜(LWW, Last Write Wins)策略。即较新的
_rev
版本会覆盖旧版本。但这种策略可能丢失数据,比如两个客户端同时更新不同字段,按LWW可能只保留最后更新的字段,另一更新字段丢失。
- 手动解决:用户可通过CouchDB的API获取冲突版本,查看内容后手动选择保留哪个版本。比如通过
根据业务需求自定义更有效的冲突处理策略
- 基于业务规则:
- 合并策略:若业务允许,可将冲突版本的不同字段进行合并。例如,对于一个用户信息文档,一个客户端更新了地址,另一个更新了电话,自定义策略可将两个更新合并。可通过编写脚本,分析冲突版本的差异,按规则合并。
- 优先级策略:根据业务对象的重要性设定优先级。比如,对于订单文档,若销售部门更新优先级高于客服部门,当两个部门更新冲突时,优先采用销售部门的更新。在代码中可根据更新来源等标识判断优先级。
- 使用外部工具或服务:
- 引入第三方冲突解决库:如
js - conflict - resolver
,可在JavaScript环境下帮助处理复杂的冲突逻辑。通过解析冲突版本的结构,按库提供的算法解决冲突。 - 借助分布式协调服务:像ZooKeeper,通过它的分布式锁机制,保证同一时间只有一个客户端能更新文档,避免冲突发生。在更新文档前,客户端先尝试获取ZooKeeper锁,获取成功才能更新。
- 引入第三方冲突解决库:如
- 用户介入:
- 提示用户解决:在应用层面,当检测到冲突时,弹出提示框,向用户展示冲突版本内容,让用户选择保留哪个版本或如何合并。可通过前端界面展示冲突字段差异,方便用户操作。