如何防止由mongodb支持的分布式nodejs web服务器体系结构中的竞争条件

这是我的问题的描述:

  1. 我有一个在负载平衡器背后的nodejs(express.js)中编写的x web工作者。 这些工作人员将数据写入mongodb(mongoose.js)
  2. 我已经设置了端点y,使得在处理程序的中间件链中的某个点处,我正在执行以下逻辑:如果请求用户存在于数据库中,那么获取它,更新一些字段然后将其存回。 如果不存在,则将其插入到mongo中。

注意! 我无法使用Mongoose的findAndUpdateOne() – 这将是primefaces – 由于域特定的逻辑,即。 如果用户已经存在用特定的值更新它,否则插入另一个值。

  1. 问题通常是,来自同一用户的两个请求(谁还没有在数据库中)将会遇到两个不同的工作人员。 当用户处理中间件时,两个工作人员都会确定用户不存在,并尝试插入并更新。 自然这会导致错误,例如。 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 })