Mongoose VersionError: No matching document found for id
Thông báo lỗi này từ Mongoose:
❗ VersionError: No matching document found for id ... version ...
🧠 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 →
__v
bị 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.