【问题标题】:MongoDB concurrent update (with sub collection)MongoDB 并发更新(带子集合)
【发布时间】:2015-10-23 09:31:06
【问题描述】:

我开始在工作中使用 MongoDB(使用 spring-data-mongo),所以一切都很好。 但我想知道 MongoDB 如何处理发生的更新?更具体地说,处理这些问题的最佳做法是什么?

例如,我有一个包含地图的文档

@Document(collection = "test)
public class Test {
   private String name;
   private Map<Long, Holder> myMap;
}

public class Holder {
   private List<Integer> list;
}


{ 
  "name": "test",
  "myMap: "{"1":"{"list":[1,2,3]}", "2":"{"list":[1,2,3]}"}"
}

Thread A: retrieves the Test Document
Thread A: gets myMap and add a new entry in the list for key "1"
Thread B: retrieves the Test Document
Thread B: gets myMap and add a new entry in the list for key "1"
Thread B: saves the Test Document
Thread A: saves the Test Document

问题是 myMap 中的内容是什么? B 或 A 添加的条目?还是两者都有?

【问题讨论】:

  • 这取决于使用的底层 MongoDB 命令,update()findAndModify()
  • 在这种情况下(我使用的是spring存储库)repository.findOne(id) ... repository.save(document);
  • 我不确定repository.save() 的内部结构。要对更新操作进行更精细的控制,您必须查看methods for the Update class,或使用findAndModify() 的原子更新。
  • 假设我正在使用 findAndModify(),有没有办法在 myMap 中“添加”(而不是完全替换)一个条目?

标签: mongodb dictionary collections concurrency updates


【解决方案1】:

您可以将$push array update operatorupdate()findAndUpdate() 一起使用。

假设一个对象像

{ name : "test", myMap : {
    "1" : { list : [1,2,3] },
    "2" : { list : [4,5,6] }
}}

你可以这样做

update(..., { $push:{ "myMap.2.list" : 8 }})    // results in "2" : {list:[4,5,6,8]}
update(..., { $push:{ "myMap.3.list" : 9 }})    // results in new entry "3" : {list:[9]}

这会将值附加到现有条目数组或创建一个新条目(使用新数组)。

来自文档:

$push 运算符将指定的值附加到数组。

如果要更新的文档中不存在该字段,则 $push 会添加以该值作为其元素的数组字段。

要完成,您应该查看其他 update operators 的文档,例如 $set$inc$max 等。


如果你只是使用

update(..., { name : "test", myMap : {
    "1" : { list : [1,2,3] },
    ...
})

在两个线程中,都不会指定结果,这取决于最后执行的更新请求。

【讨论】:

  • 有趣。我不知道可以使用 myMap.2(带点)来指定将对象附加到哪个键。我用更完整的模型稍微修改了我的问题。套装会是什么样子? myMap.2.list ?
  • @Johny19,我也相应地更新了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-30
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-23
相关资源
最近更新 更多