mongoose在插入文檔時會自動為文檔生成版本號字段__v旅择,每使用save()進(jìn)行一次保存产园,版本號都會更新,并且是遞增的滔驶。
const schema = new Schema({ name: 'string' });
const Thing = mongoose.model('Thing', schema);
const thing = new Thing({ name: 'mongoose v3' });
await thing.save(); // { __v: 0, name: 'mongoose v3' }
如果想要自定義VersionKey遇革,可以聲明一個Schema:
new Schema({..}, { versionKey: '_somethingElse' }) //給版本號換一個名字
new Schema({..}, { versionKey: false }); //在你新建模型的時候關(guān)閉就可以了
const Thing = mongoose.model('Thing', schema);
const thing = new Thing({ name: 'no versioning please' });
thing.save(); // { name: 'no versioning please' }
VersionKey的作用就是在并發(fā)修改文檔時避免出現(xiàn)不可預(yù)知的錯誤。比如存在一個文檔:
article = {
title: 'Title',
comment: [
'aaa',
'bbb',
'ccc'
]
};
假設(shè)兩個用戶同時讀取了這個文檔揭糕,然后用戶A嘗試執(zhí)行:
article.comment[2] = 'ddd';
同時用戶B嘗試從comment數(shù)組中刪除第二項萝快。此時用戶A的操作如果比較慢,那么有可能會發(fā)生數(shù)組越界訪問的情況著角。所以通過mongoose通過比較待存入的文檔中的VersionKey與數(shù)據(jù)庫中的是否一致就可以知道在執(zhí)行過程中有沒有發(fā)生并發(fā)修改揪漩,有則拋出異常。
此外吏口,在for循環(huán)中使用異步數(shù)據(jù)庫操作奄容,即使沒有并發(fā)調(diào)用,也有可能出現(xiàn)該問題产徊。