【发布时间】:2017-07-20 04:18:33
【问题描述】:
假设我们有一个简单的应用程序,用户可以在其中创建产品并对其进行评论。 products 和 cmets 的架构可以是:
var productSchema = new mongoose.Schema({
author_id: ObjectId,
description: String
});
var commentSchema = new mongoose.Schema({
product_id: ObjectId,
author_id: ObjectId,
message: String
});
我们希望确保每条评论都指向现有产品。这可以通过 mongoose pre save hook 轻松完成:
commentSchema.pre("save", function(next) {
Product.count({ _id: this.product_id }, function(err, count) {
if (err || !count) {
next(new Error("Could not find product"));
} else {
next();
}
});
});
此外,如果用户删除了产品,我们希望删除该产品上的所有 cmets。这可以使用 pre remove hook 轻松完成:
productSchema.pre("remove", function(next) {
Comment.remove({ product_id: this._id }, next);
});
但是如果用户 A 删除了一个产品,同时用户 B 开始使用该产品呢?
可能会发生以下情况:
Call pre save hook for new comment, and check if product exists
Call pre remove hook for product, and remove all comments
In pre save hook, done checking: product actually exists, call next
Comment saved
In pre remove hook, done removing comments: call next
Product removed
最终结果是我们有一个评论指向一个不存在的产品。
这只是导致这种情况发生的众多情况之一。如何防止这种极端情况?
【问题讨论】:
-
您可能会有延迟,用户无法发表评论。我认为这就是堆栈的作用
标签: javascript node.js mongodb mongoose concurrency