我在Sails.js(v0.12.13)工作,我在控制器中的一个动作如下:
create: function(req, res){
var comment = req.body;
var image_id = req.params.id;
Image.findOne(image_id).populate('comments').exec(function(err, image){
image.messages.add(comment);
image.save(function(err){
return res.created(comment);
});
});
}
(错误处理被忽略)
基本上,这会为comment
添加image
。首先,我需要获取图像,使用它的注释,将新注释添加到数组中,然后再次保存。
然而,我的直觉是有两个不同的人试图添加评论的情况,事件的顺序是:
这可以在Node.js中发生吗?,还是有什么可以防止这种情况发生?
我在网站上看过一些例子,例如http://sailsjs.com/documentation/reference/waterline-orm/populated-values/add,他们会做类似的事情。如果竞争条件可能发生,那么Sail.js对我来说变得无法使用,因为我觉得这些事情非常重要。
提前致谢。
答案 0 :(得分:2)
简短回答:不用担心,您不会以这种方式丢失/覆盖数据。
这可以在Node.js中发生吗?
是
有什么可以防止这种情况发生吗?
是
此条件不特定于Node.js 或异步,基于事件循环的执行 由于线程抢占,2个线程处理其他语言(Java,Ruby等)的2个请求会发生类似的事情。
{ id: 1, comments: [1, 2] }
{ id: 1, comments: [1, 2] }
{ id: 1, comments: [1, 2, 3] }
。在保存时,它确保只有1,2,3条评论与图像1相关联。{ id: 1, comments: [1, 2, 4] }
。在保存时,它确保只有1,2,4条评论与图像1相关联,从而删除评论3 Comment#3
添加。像{ id: 1, comments: { value: [1, 2], addModels: [3] }
这样的东西。保存时,会在数据库中的Comment#3
和Image#1
之间创建关联。Comment#4
添加。像{ id: 1, comments: { value: [1, 2], addModels: [4] }
这样的东西。在保存时,会在数据库中的Comment#4
和Image#1
之间创建关联。较早创建的关联Comment#3
未触及。答案 1 :(得分:0)
docs表示:
查询对象(又称查询实例)是可链接的延迟对象 从.find()和.create()等模型方法返回。他们代表 一个尚未完成的意图来获取或修改记录 数据库中。
所以不,findOne()
不会阻止。这一切都取决于特定数据库引擎的exec()
方法。如果数据库驱动程序具有非阻塞API,则不会阻塞。竞争条件还取决于底层DBMS实现。但是findOne
不会导致竞争条件。
答案 2 :(得分:-1)