3

我有一个例程来更新数据库中的值,然后在一秒钟的计时器上查找它。这是一个简单的设置...

function checkStatusAndDoWork(){
  userMongooseModel.find({'someCondition': { $gte:(new Date()) }}, function(err, userModel){
      if (userModel.length > 0) { //there is only one document in the return.
          doSomeWorkThatTakes20seconds();
          // Update the Mongo document with a new next time
          userMongooseModel.update( {_id:userModel[0]._id}, {'someCondition': Date.now() + 10000}, function(err, numAffected){ 
              console.log('Checkpoint 1'); 
              setTimeout(checkStatusAndDoWork, 1000); //repeat the loop after 1 second.
          })
      } else {
          console.log('Checkpoint 2');
          setTimeout(checkStatusAndDoWork, 1000); // otherwise repeat the loop after 1 second anyways.
      }
  }
}

情况——

通常,一切正常。我看到以下内容:

Checkpoint 1
Checkpoint 2
Checkpoint 2
...
Checkpoint 2
Checkpoint 1
Checkpoint 2
Checkpoint 2
...

但是如果我打开 MongoExplorer 并开始查看文档,那么如果我碰巧时间正好,我会看到以下内容......

Checkpoint 1
Checkpoint 2
Checkpoint 2
...
Checkpoint 2
Checkpoint 1
Checkpoint 1
Checkpoint 1
Checkpoint 1
Checkpoint 1
Checkpoint 2
Checkpoint 2
...

似乎更新进入了 Mongo 队列,因此文档没有立即更新。这会导致 find() 返回 true 并重复转到“检查点 1”,直到数据库写入完成。

我怎样才能避免这种竞争条件?

注意:我重写了这个如何在 javascript问题中使用带有双回调的 setTimeout 来简化。

4

0 回答 0