【问题标题】:MongoDB: findOneAndUpdate seems to be not atomicMongoDB:findOneAndUpdate 似乎不是原子的
【发布时间】:2019-01-04 04:45:13
【问题描述】:

我使用 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
添加 活动2
添加 活动3
添加 活动4
对于事件 1 得到的价值:1
事件3 得到的价值:4
对于事件 2 得到的价值:2
事件4 得到值:3

我得出的结论是,我的代码无法自动运行。 这些事件在正确的索引中出现,但在 findOneAndUpdate 之后没有附加正确的顺序。有谁能帮帮我吗?

【问题讨论】:

  • “原子地”是什么意思?另外,您能否更好地描述此流程的用例?我觉得必须有一个比期望异步 javascript 事件以特定顺序发生更好的解决方案。
  • findOneAndUpdate 不是原子的。你用的是哪个版本的mongodb?

标签: node.js mongodb


【解决方案1】:

原子数据库操作并不意味着它们在请求运行时锁定数据库。也许您正在按顺序获取请求,但它们没有按顺序执行,也没有在后端执行,也没有在数据库中执行。
您需要做的是从“事件”集合中读取最后一个文档索引。如果它比您当前的请求索引少一个,则插入 else 等待并重试。
尽管如果一个事件由于网络错误或其他原因而失败,这可能会导致问题。然后您的请求处理将停止。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 2022-11-10
    • 2022-11-26
    相关资源
    最近更新 更多