在NestJS中使用Mongoose操作MongoDB时,如何处理文档版本冲突?
基于Mongoose __v属性的乐观锁实现
下面是一种利用Mongoose内置__v版本字段实现乐观锁的方案,用于在更新文档前检测版本冲突:
async miseAJourDoc(docToUpdate: MyClass) { const updatedDoc = await this.docModel.findOneAndUpdate( { _id: docToUpdate._id, __v: docToUpdate.__v }, { ...docToUpdate, $inc: { __v: 1 } }, { new: true }, ).exec(); if (!updatedDoc) { // 处理当前文档版本与之前获取版本不匹配的情况 throw new ConflictException('该文档已被其他用户修改,请重新尝试。'); } return updatedDoc; }
实现逻辑说明
- 查询条件同时匹配文档
_id和传入的__v版本号,确保只有数据库中文档版本与客户端提交版本一致时,才会执行更新操作 - 使用
$inc: { __v: 1 }自动递增版本号,避免手动维护版本值带来的误差 - 若
findOneAndUpdate返回null,说明版本不匹配(文档已被其他操作修改),此时抛出冲突异常提醒用户重试
注意事项
- 客户端发起更新请求时,必须携带从数据库获取的最新
__v值,否则会直接触发版本冲突 - 该方案依赖Mongoose内置的版本字段,无需额外在Schema中定义(Mongoose默认会为Schema添加
__v字段,除非手动禁用) - 高并发场景下,这种乐观锁机制能有效避免并发更新导致的数据覆盖问题
内容的提问来源于stack exchange,提问作者Raymond SADIO
相关产品推荐
相关产品推荐

