面试题答案
一键面试检测版本冲突
- 文档修订版本号:CouchDB 使用
_rev
字段来跟踪文档的版本。每次文档更新时,_rev
会递增。当客户端尝试更新文档时,它必须在请求中包含当前的_rev
。如果服务器上的_rev
与客户端提供的不一致,就表明发生了版本冲突。例如,客户端 A 获取文档时_rev
为 1 - abc,在客户端 A 处理期间,客户端 B 更新了文档,_rev
变为 2 - def,此时客户端 A 再尝试更新,就会因_rev
不匹配而检测到冲突。 - 基于时间戳:虽然不是主要的冲突检测方式,但在某些情况下,CouchDB 可能会考虑文档修改的时间戳来辅助判断冲突。不过这种方式相对次要,
_rev
字段是核心检测依据。
处理版本冲突
- 客户端重试:当检测到冲突时,CouchDB 会返回 HTTP 409 Conflict 状态码给客户端。客户端收到该状态码后,通常需要重新获取最新版本的文档(包含最新
_rev
),将其与本地修改合并(如果可能),然后再次尝试更新。例如,客户端 A 收到 409 错误后,重新获取文档,发现客户端 B 对文档做了一些修改,客户端 A 将自己的修改与客户端 B 的修改合并(比如合并文本内容等),然后带着新的_rev
再次发起更新请求。 - 手动解决:如果自动合并不可行,客户端需要手动解决冲突。这可能涉及用户干预,比如在一个协同编辑文档的场景中,提示用户解决不同编辑者对同一文档不同部分的修改冲突,然后由用户决定如何整合这些修改,最后客户端再发起更新请求。
- 服务器端合并(有限支持):CouchDB 本身并没有强大的自动服务器端合并机制,但可以通过编写自定义的冲突处理函数(使用 JavaScript 编写)来实现部分自动合并逻辑。例如,对于简单的数值相加等情况,可以编写函数实现服务器端自动合并,减少客户端手动干预。不过这种方式对复杂数据结构的合并支持有限。
关键技术点
- MVCC 机制:多版本并发控制(MVCC)是核心机制,允许同时存在同一文档的多个版本,通过
_rev
字段区分版本,确保数据一致性和并发更新。 - HTTP 状态码:使用 HTTP 409 Conflict 状态码准确告知客户端发生了版本冲突,这是客户端了解冲突并进行后续处理的关键信号。
- 文档修订跟踪:精确跟踪
_rev
字段的变化,保证每次更新都基于最新版本,避免覆盖丢失更新。 - 自定义冲突处理函数:虽然不是默认强大的机制,但自定义冲突处理函数扩展了处理复杂冲突场景的可能性,为开发者提供了一定灵活性。