Johny19
Johny19

Reputation: 5582

MongoDB concurrent update (with sub collection)

I started using MongoDB (With spring-data-mongo) at work and so fare all good. But I was wondering how does MongoDB deals with occurrent update? And more specifically what are the best practices to handle these ?

For example I have a Document that contains a Map

@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

The question is what will be in the myMap ? the entry added by B or A ? or both ?

Upvotes: 2

Views: 1204

Answers (1)

Jonas Malaco
Jonas Malaco

Reputation: 1557

You can use the $push array update operator with either update() or findAndUpdate().

Assuming an object like

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

you can simply do

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]}

This will either append the value to the existing entry array or create a new entry (with a new array).

From the docs:

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.

For completion, you should check out the docs of other update operators like $set, $inc, $max, etc.


If you simply use

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

in both threads, the result won't be specified and will depend on which update request gets executed last.

Upvotes: 1

Related Questions