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