MongoDB 并发更新(带子集合)

MongoDB concurrent update (with sub collection)

我开始在工作中使用 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 添加的条目?或两者兼而有之?

您可以将 $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]}

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

来自文档:

The $push operator appends a specified value to an array.

If the field is absent in the document to update, $push adds the array field with the value as its element.

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


如果你只是使用

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

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