面试题答案
一键面试CouchDB处理并发写冲突的策略
- 版本控制机制:CouchDB使用基于修订版本号(
_rev
)的机制来跟踪文档的变化。每次文档被修改,其_rev
值都会更新。当客户端尝试写入文档时,必须提供当前的_rev
值。如果提供的_rev
值与服务器上的文档_rev
值不匹配,说明在客户端读取文档后,该文档已被其他客户端修改,服务器会返回写冲突错误。 - 冲突文档存储:当发生写冲突时,CouchDB不会简单地覆盖较新的版本,而是将冲突的文档版本都保留下来。这些冲突的文档版本被存储在
_conflicts
数组中,每个冲突版本都有其自己的_rev
值。 - 冲突解决:最终一致性模型下,应用程序开发者需要在后续阶段决定如何解决这些冲突。CouchDB提供了一些工具和API来帮助开发者处理冲突,例如获取冲突文档的所有版本,手动选择要保留的版本等。
代码示例(以Python为例,使用couchdb
库)
import couchdb
# 连接到CouchDB服务器
server = couchdb.Server('http://localhost:5984')
db = server['your_database']
# 尝试获取并更新文档
try:
doc_id = 'your_document_id'
doc = db[doc_id]
doc['some_field'] = 'new_value'
db.save(doc)
except couchdb.http.ResourceConflict:
print("写冲突发生,尝试解决冲突...")
# 获取冲突文档
conflict_doc = db.get(doc_id, conflicts=True)
conflict_revs = conflict_doc['_conflicts']
print("冲突的修订版本:", conflict_revs)
# 选择一个修订版本(这里简单选择最新的,实际应用中需更复杂逻辑)
latest_rev = max(conflict_revs, key=lambda x: int(x.split('-')[1]))
new_doc = db.get(doc_id, rev=latest_rev)
# 更新新文档并保存
new_doc['some_field'] = 'new_value'
db.save(new_doc)
print("冲突解决,文档已更新。")
上述代码中,首先尝试常规地获取并更新文档。如果发生ResourceConflict
异常,说明有写冲突,此时获取冲突文档的所有冲突版本,选择其中最新的版本(实际应用中可能需要更复杂的逻辑来选择),对其进行更新并保存,从而解决冲突。