首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检查mongodb文档在读取后是否已被修改,但在写入该文档之前?

如何检查mongodb文档在读取后是否已被修改,但在写入该文档之前?
EN

Stack Overflow用户
提问于 2022-07-25 16:53:58
回答 1查看 31关注 0票数 1

考虑一下将Address文档ID嵌入到User文档中的用例。线程12同时运行,然后是Check results线程。

用户:

代码语言:javascript
复制
addresses: [1, 2, 3]

异步线程1:

代码语言:javascript
复制
user = userCollection.find(userId)
user.addresses.push(4)
userCollection.update(user)

异步线程2:

代码语言:javascript
复制
user = userCollection.find(userId)
user.addresses.push(5)
userCollection.update(user)

检查结果:

代码语言:javascript
复制
user = userCollection.find(userId)
user.addresses.includes(4) // result is non-deterministic
user.addresses.includes(5) // result is non-deterministic

是否需要在应用程序级别实现自己的文档级别锁,以防止多线程应用程序覆盖其他线程当前正在写入的数据?

也许我缺少了一个内置的原子函数来附加到数组中?但是,查找/替换的情况如何呢?我不只是想‘推’一个新的值到数组,但找到一个旧的ID已被删除,然后删除它。同时,另一个线程想要添加到数组中。老实说,我不知道什么是最简单的解决办法。我用psuedo-javascript编写了这个问题,但是我在这个项目中使用了golang。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-25 17:19:22

官方医生称,

在MongoDB中,写入操作是单个文档级别上的原子操作,即使该操作修改单个文档中的多个嵌入文档。

对于单个文档,您不需要太在意原子性。对于给定的示例,您可以简单地使用聚合管道进行更新,该管道可用于MongoDB v4.2+。

代码语言:javascript
复制
db.collection.update({
  "userId": 1
},
[
  {
    "$set": {
      "addresses": {
        "$setUnion": [
          {
            "$filter": {
              "input": "$addresses",
              "as": "a",
              "cond": {
                $ne: [
                  "$$a",
                  3    // element you want to remove
                ]
              }
            }
          },
          // element you want to add
          [
            4
          ]
        ]
      }
    }
  }
])

这是供您参考的蒙戈游乐场

如果需要处理多文档原子性,可以选择交易记录,这是MongoDB v4.0+可用的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73112796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档