Mongoose VersionError: No matching document found for id
/ 2 min read
Table of Contents
Thông báo lỗi này từ Mongoose:
Giải thích:
Mongoose bật Optimistic Concurrency Control (OCC) theo mặc định nếu:
- Bạn dùng
.save()trên một document có__v(version key). - Giữa lúc bạn đang xử lý, document đó bị người khác update →
__vbị thay đổi. - Khi bạn gọi
.save(), Mongoose kiểm tra__v. Nếu không khớp → báo lỗi như trên.
🔍 Ví dụ cụ thể:
const doc1 = await MyModel.findById(id);const doc2 = await MyModel.findById(id);
doc1.name = 'Alice';await doc1.save(); // OK, __v tăng từ 5 → 6
doc2.name = 'Bob';await doc2.save(); // ❌ lỗi: version mismatch (__v = 5 expected, nhưng giờ là 6)Cách khắc phục
1. Dùng updateOne() hoặc findByIdAndUpdate() với atomic operator
✅ Không dùng .save() thì Mongoose không check __v
await MyModel.updateOne( { _id: id }, { $set: { name: 'Bob' } });2. Retry lại khi gặp lỗi version
Bạn có thể bắt lỗi và load lại document:
try { await doc.save();} catch (err) { if (err.name === 'VersionError') { const latestDoc = await MyModel.findById(doc._id); // xử lý lại và lưu lại }}3. Tắt OCC (Không khuyến khích)
const schema = new mongoose.Schema({ ... }, { optimisticConcurrency: false });⚠️ Nếu bạn tắt OCC thì phải tự xử lý tránh conflict.
4. Dùng $inc, $set, $push qua updateOne() nếu có nhiều API gọi liên tục
Với API “gọi liên tục”, .save() dễ gây xung đột → chuyển sang dùng updateOne() là tốt nhất.