MongoDB - operacje atomowe
Dane modelu dla operacji atomowych
Zalecanym podejściem do zachowania niepodzielności byłoby przechowywanie wszystkich powiązanych informacji, które są często aktualizowane razem w jednym dokumencie przy użyciu embedded documents. Zapewniłoby to, że wszystkie aktualizacje pojedynczego dokumentu są niepodzielne.
Załóżmy, że stworzyliśmy kolekcję o nazwie productDetails i wstawiliśmy do niej dokumenty, jak pokazano poniżej -
>db.createCollection("products")
{ "ok" : 1 }
> db.productDetails.insert(
{
"_id":1,
"product_name": "Samsung S3",
"category": "mobiles",
"product_total": 5,
"product_available": 3,
"product_bought_by": [
{
"customer": "john",
"date": "7-Jan-2014"
},
{
"customer": "mark",
"date": "8-Jan-2014"
}
]
}
)
WriteResult({ "nInserted" : 1 })
>
W tym dokumencie umieściliśmy informacje o kliencie, który kupuje produkt w formacie product_bought_bypole. Teraz za każdym razem, gdy nowy klient kupi produkt, najpierw sprawdzimy, czy produkt jest nadal dostępny za pomocąproduct_availablepole. Jeśli to możliwe, zmniejszymy wartość pola product_available, a także wstawimy osadzony dokument nowego klienta w polu product_bought_by. UżyjemyfindAndModify polecenie dla tej funkcji, ponieważ wyszukuje i aktualizuje dokument w tym samym czasie.
>db.products.findAndModify({
query:{_id:2,product_available:{$gt:0}},
update:{
$inc:{product_available:-1},
$push:{product_bought_by:{customer:"rob",date:"9-Jan-2014"}}
}
})
Nasze podejście do osadzonego dokumentu i za pomocą zapytania findAndModify zapewnia, że informacje o zakupie produktu są aktualizowane tylko wtedy, gdy produkt jest dostępny. Cała ta transakcja znajdująca się w tym samym zapytaniu jest atomowa.
W przeciwieństwie do tego rozważmy scenariusz, w którym mogliśmy oddzielnie zachować dostępność produktu i informacje o tym, kto kupił produkt. W takim przypadku najpierw sprawdzimy, czy produkt jest dostępny za pomocą pierwszego zapytania. Następnie w drugim zapytaniu zaktualizujemy informacje o zakupie. Jednak możliwe jest, że pomiędzy wykonaniem tych dwóch zapytań inny użytkownik kupił produkt i nie jest on już dostępny. Nie wiedząc o tym, nasze drugie zapytanie zaktualizuje informacje o zakupie w oparciu o wynik pierwszego zapytania. Spowoduje to niespójność bazy danych, ponieważ sprzedaliśmy produkt, który nie jest dostępny.