skip to content
namnh

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 → __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.