面试题答案
一键面试解决冲突的方法
- 最后写入者胜出(Last Write Wins, LWW):以最后修改时间为准,新的修改覆盖旧的修改。这种方法简单直接,但可能会丢失早期有价值的修改。
- 手动合并:开发者根据业务逻辑,手动合并不同用户对文档的修改。例如,对于文档中的数组类型数据,将不同用户添加的元素合并到一起。
- 用户选择:向用户展示冲突版本,由用户决定采用哪个版本或如何合并。
CouchDB内部处理冲突的机制
CouchDB使用多版本并发控制(MVCC)来处理冲突。当发生冲突时,CouchDB会保留所有冲突的文档版本。每个文档都有一个_rev
(修订版本号)字段,每次文档修改时,_rev
会更新。冲突的文档版本会在_conflicts
数组中列出,每个元素是冲突版本的_rev
。
手动处理冲突的代码示例(以Node.js为例)
const nano = require('nano')('http://localhost:5984');
const dbName = 'your_database_name';
const docId = 'your_document_id';
// 获取包含冲突的文档
nano.db.get(dbName, docId, { conflicts: true }, (err, body) => {
if (err) {
console.error('Error getting document:', err);
return;
}
if (body._conflicts) {
// 手动选择一个版本(这里简单选择第一个冲突版本)
const chosenRev = body._conflicts[0];
// 获取选择版本的文档内容
nano.db.get(dbName, docId, { rev: chosenRev }, (err, chosenBody) => {
if (err) {
console.error('Error getting chosen revision:', err);
return;
}
// 这里可以根据业务逻辑合并文档,假设直接使用选择的版本
const newDoc = chosenBody;
// 保存新文档,会生成新的_rev
nano.db.insert(newDoc, docId, (err, insertResult) => {
if (err) {
console.error('Error inserting new document:', err);
return;
}
console.log('Conflict resolved, new document inserted:', insertResult);
});
});
} else {
console.log('No conflicts found.');
}
});
此代码示例首先获取包含冲突的文档,然后选择一个冲突版本,最后将选择的版本作为新文档插入,从而解决冲突。实际应用中,手动合并逻辑会更加复杂,需要根据文档结构和业务需求进行定制。