如何防止由mongodb支持的分布式nodejs web服务器体系结构中的竞争条件
这是我的问题的描述:
- 我有一个在负载平衡器背后的nodejs(express.js)中编写的x web工作者。 这些工作人员将数据写入mongodb(mongoose.js)
- 我已经设置了端点y,使得在处理程序的中间件链中的某个点处,我正在执行以下逻辑:如果请求用户存在于数据库中,那么获取它,更新一些字段然后将其存回。 如果不存在,则将其插入到mongo中。
注意! 我无法使用Mongoose的findAndUpdateOne() – 这将是primefaces – 由于域特定的逻辑,即。 如果用户已经存在用特定的值更新它,否则插入另一个值。
- 问题通常是,来自同一用户的两个请求(谁还没有在数据库中)将会遇到两个不同的工作人员。 当用户处理中间件时,两个工作人员都会确定用户不存在,并尝试插入并更新。 自然这会导致错误,例如。 validation错误:我已经为每个用户validation和其他设置了一个唯一的电子邮件
我怎样才能防止这个?
您可以使用$set
和$setOnInsert
更新运算符来实现这一点。
从MongoDB $ setOnInsert文档 :
如果使用upsert:true的更新操作导致插入文档,则$ setOnInsert将指定的值分配给文档中的字段。 如果更新操作没有导致插入,$ setOnInsert什么也不做。
和
如果使用upsert:true的db.collection.update()find了匹配的文档,那么MongoDB将执行更新,应用$ set操作,但忽略$ setOnInsert操作。
所以,这应该做的伎俩:
var now = Date.now(); Users.update({ _id: 1 }, { $set: { updatedAt: now }, $setOnInsert: { createdAt: now } }, {upsert: true}, function(err, doc) { // resultant doc is available here })