MongoDB并发更新(带子集合)

时间:2015-10-23 09:31:06

标签: mongodb dictionary collections concurrency updates

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

1 个答案:

答案 0 :(得分:1)

您可以将$push array update operatorfindAndUpdate(){ 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]}

你可以简单地做

$set

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

来自文档:

  

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

     

如果要更新的文档中没有该字段,$ push会添加数组字段,并将值作为其元素。

完成后,您应该查看其他update operators的文档,例如$inc$maxupdate(..., { name : "test", myMap : { "1" : { list : [1,2,3] }, ... }) 等。

如果您只是使用

{{1}}

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