我正在使用nodejs + mongodb作为广泛分布的Web应用程序的后端。我有一系列事件,需要按特定顺序进行。有多种服务可以生成这些事件,我的应用程序应在事件进入时对其进行处理和存储,并且在任何给定的时间我都希望它们以正确的顺序进行处理。
我不能依靠时间戳,因为javascript仅提供以毫秒为单位的时间戳,对于我的情况来说不够准确。
我的数据库中有两个集合。一个存储事件,另一个存储索引,代表我的事件顺序。我尝试使用findOneAndUpdate来原子地增加索引。但是,这似乎不起作用。
console.log('Adding');
console.log(event.type);
this._db.collection('evtidx').findOneAndUpdate({ id : 'index' }, { $inc: { value : 1 } }, (err, res) => {
console.log('For '+event.type);
console.log('Got value: '+res.value.value);
event.index = res.value.value;
this._db.collection('events').insertOne(event, (err, evtres) => {
if (err) {
throw err;
}
});
});
当我检查上面代码的输出时,我看到:
添加
活动1
新增中
Event2
新增中
Event3
新增中
Event4
对于事件1
得到的值:1
对于事件3
得到的值:4
对于Event2
得到的值:2
对于事件4
得到的值:3
对我的结论是,我的代码不是原子工作的。 事件以正确的索引进来,但是在findOneAndUpdate之后没有正确的顺序附加到事件。有人可以帮我吗?
答案 0 :(得分:1)
原子数据库操作并不意味着它们在请求运行时锁定数据库。也许您是在按顺序获取请求,但是它们没有按顺序执行,也没有在后端或数据库中执行。
您需要做的是从“事件”集合中读取最后一个文档索引。如果小于1,则表示您当前的请求索引,然后插入else,然后重试。
尽管如果一个事件由于网络错误或其他原因而失败,则可能导致问题。然后您的请求处理将停止。