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.