2012-04-06 11 views
7

MongoDB ma obsługę aktualizacji atomowych. To znaczy. Mogę być pewien, że po aktualizacji dokumentu żadna inna aktualizacja nie zastąpi mojej poprzedniej zmiany. Moje pytanie dotyczy kombinacji zapytania i instrukcji aktualizacji i najlepiej ilustruje to przykład przedstawiony poniżej.Czy atomowość aktualizacji MongoDB dotyczy zarówno zapytania, jak i modyfikacji?

db.foo.update(
{ state : 1, players: { $size: 2 } } , 
{ $push: { players : { new player document } } }, 
false , true); 

W powyższym przykładzie, chcę tylko do pchania nowego gracza na zbiór graczy, jeśli liczba graczy jest równa 2. Biorąc pod uwagę powyższe zestawienie zapytań i aktualizacji, to możliwe, że dwa jednoczesne aktualizacje zarówno popchnąć gracza na ten sam dokument, ponieważ w chwili czytania dokumentu jego gracze $ size to 2? To znaczy. czy rozpiętość atomowości w zapytaniu i aktualizuje część instrukcji aktualizacji, czy nie?

Edit Więcej sekwencja dogłębne wydarzeń:

Rozważmy wypalania samą aktualizację dwukrotnie (U1 i U2) w tym samym czasie. Czy możliwa jest następująca sekwencja zdarzeń, czy nie?

  1. U1 stwierdza, że ​​dokument nr 1 pasuje do części zapytania instrukcji aktualizacji .
  2. U2 stwierdza, że ​​dokument nr 1 pasuje do części zapytania dotyczącej instrukcji aktualizacji.
  3. U1 przesuwa nowego gracza w dokumencie nr 1.
  4. U2 popycha nowego gracza w dokumencie nr 1.

Rezultatem jest to, że dokument # 1 zawiera jeszcze jednego gracza, niż się spodziewano, ponieważ zarówno U1, jak i U2 były pod wrażeniem, że dokument nr 1 zawiera tylko dwóch graczy.

Odpowiedz

0

Aktualizacja: nie jestem pewien mojej wiedzy ... Zobacz "The ABA Nuance". Proszę nie akceptować tej odpowiedzi (lub mojego komentarza poniżej), ponieważ prawdopodobnie nie jest to poprawne. Chciałbym być poprawiony.


Twój wyjaśnienie atomowa jest niepoprawna (mogę mieć pewność, że gdy dokument jest aktualizowana żadna inna zmiana zastąpi mój poprzedni zmianę). Inne aktualizacje mogą (i będą) nadpisywać twoją zmianę. Ale nie zrobią tego w sposób, który zakłócałby spójność twojego zapytania.

Ważne jest, aby wiedzieć, że aktualizacje MongoDB to atomic on single document. Kiedy dokument pasuje do zapytania, jest "zablokowany" i gotowy do aktualizacji. Zauważ, że twoja aktualizacja ($push) działa wewnątrz tego samego dokumentu, który był zablokowany. Po zakończeniu aktualizacji blokada zostaje zwolniona.

Nie jestem pewien, czy rozumiem „ma rozpiętość atomowości poprzek zapytań i aktualizacji części zestawienia aktualizacji lub nie”, ale: środki atomowe że inne zapytań nie może bałagan z naszego zapytania. Nasze zapytanie może zmienić dane, które są "zablokowane" samodzielnie.

Nota prawna: Nie jestem wtajemniczony w wewnętrzne mechanizmy, których MongoDB używa do zapewnienia tej atomowości, więc opis ten może nie być widoczny z technicznego punktu widzenia (zwłaszcza w związku z blokowaniem) - ale jest to ważne pod względem koncepcyjnym. Tak to działa z zewnętrznego punktu widzenia.

+0

Dziękuję za odpowiedź. Zaktualizowałem moje pytanie sekwencją zdarzeń, które mam nadzieję nieco wyjaśnić. Teraz zdaję sobie sprawę, że to, o co pytam, to nie atomowość, ale transakcja (blokada) na poziomie dokumentu. –

+0

Tak, to rzeczywiście wyjaśnia pytanie. Nie masz się czego obawiać. Nic nie może zmienić dokumentu między znalezieniem a aktualizacją (kroki 2 i 4) lub operacja nie byłaby atomowa. Jeśli nie działa w ten sposób, oznacza to błąd i powinien zostać zgłoszony jako taki. – johndodo

0

Dzięki sekwencji zdarzeń, które zapisałeś, możesz mieć jednego gracza za dużo.Aktualizacje "znajdź" i "zaktualizuj" bardzo przypominają robienie tego samemu z "znalezieniem", a następnie "aktualizacją" każdego z powtarzanych dokumentów. Prawdopodobnie chcesz rzucić okiem na operatora "$ atomic": http://www.mongodb.org/display/DOCS/Atomic+Operations#AtomicOperations-ApplyingtoMultipleObjectsAtOnce

+1

Należy zauważyć, że OP wydaje tylko 2 aktualizacje (U1 i U2), kroki są po to, aby zilustrować możliwy konflikt. – johndodo

Powiązane problemy