面试题答案
一键面试- _rev字段基础理解
- 在CouchDB中,每个文档都有一个
_rev
字段。这个字段表示文档的版本号。每次文档被修改并保存时,CouchDB会自动更新_rev
字段的值。其格式通常类似1-abcdef123456
,其中1
是版本号部分,abcdef123456
是基于文档内容生成的哈希值。
- 在CouchDB中,每个文档都有一个
- 冲突场景及_rev字段作用
- 场景一:多个客户端同时修改同一文档
- 假设有两个客户端A和B同时获取了文档
doc1
,此时doc1
的_rev
为1 - xyz
。 - 客户端A对文档进行了修改并保存,CouchDB会将
doc1
的_rev
更新为2 - abc
,因为文档内容发生了改变。 - 几乎同时,客户端B也对文档进行了修改并尝试保存。由于在B获取文档后,文档已经被A修改过,CouchDB会检测到冲突。此时,B保存的文档会被标记为冲突文档,CouchDB会给它一个新的
_rev
,例如2 - def
,同时保留A保存的版本2 - abc
。 - 开发者识别冲突:当开发者查询该文档时,会发现文档有多个
_rev
版本,这就表明发生了冲突。在CouchDB中,可以通过?conflicts=true
的查询参数获取包含冲突信息的文档,其中会列出所有冲突的_rev
版本。 - 开发者解决冲突:开发者可以根据冲突的
_rev
版本对应的文档内容,人工决定如何合并这些修改。例如,可以对比2 - abc
和2 - def
两个版本的文档差异,然后手动将两个版本的有用修改合并到一个新的文档版本中,保存时CouchDB会生成一个新的_rev
,如3 - ghi
。
- 假设有两个客户端A和B同时获取了文档
- 场景二:文档删除与修改冲突
- 假设客户端A获取文档
doc2
,_rev
为1 - pqr
。 - 客户端A决定删除
doc2
,CouchDB会将doc2
标记为已删除,同时更新_rev
,比如变为2 - stu
,这实际上是一个删除标记版本。 - 与此同时,客户端B也获取了
doc2
(_rev
为1 - pqr
),并对其进行修改后尝试保存。CouchDB会检测到冲突,因为在B获取后文档已经被A删除。B保存的文档会有一个新的_rev
,比如2 - vwx
,并且与删除标记版本2 - stu
形成冲突。 - 开发者识别冲突:同样,通过查询带
?conflicts=true
参数,开发者会看到存在两个冲突的_rev
版本,一个是删除标记版本,一个是修改后的版本。 - 开发者解决冲突:开发者需要决定是保留修改后的文档(撤销删除操作),还是坚持删除。如果保留修改后的文档,需要将删除标记版本忽略,并将修改后的版本作为有效的文档版本,CouchDB会为其生成新的
_rev
。如果坚持删除,就需要忽略修改后的版本。
- 假设客户端A获取文档
- 场景一:多个客户端同时修改同一文档