NodeJS中使用mongoose时的VersionKey问题

mongoose在插入文档时会自动为文档生成版本号字段__v,每使用save()进行一次保存,版本号都会更新,并且是递增的。

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 }); //在你新建模型的时候关闭就可以了
const Thing = mongoose.model('Thing', schema);
const thing = new Thing({ name: 'no versioning please' });
thing.save(); // { name: 'no versioning please' }

VersionKey的作用就是在并发修改文档时避免出现不可预知的错误。比如存在一个文档:

article = {
  title: 'Title',
  comment: [
    'aaa',
    'bbb',
    'ccc'
  ]
};

假设两个用户同时读取了这个文档,然后用户A尝试执行:

article.comment[2] = 'ddd';

同时用户B尝试从comment数组中删除第二项。此时用户A的操作如果比较慢,那么有可能会发生数组越界访问的情况。所以通过mongoose通过比较待存入的文档中的VersionKey与数据库中的是否一致就可以知道在执行过程中有没有发生并发修改,有则抛出异常。
此外,在for循环中使用异步数据库操作,即使没有并发调用,也有可能出现该问题。

猜你喜欢

转载自blog.csdn.net/weixin_34244102/article/details/88252193