MongoDB - Atomic Operations

MongoDB - Atomic Operations

MongoDB does not support multi-document atomic transactions . However, it provides atomic operations on a single document. Thus, if a document has one hundred fields, the update statement will either update all fields or none, hence maintaining atomicity at the document level.

Model data for atomic operations

The recommended approach for maintaining atomicity is to store all related information that is frequently updated together in the same document using inline documents . This will ensure that all updates to a single document are atomic.

Consider the following product document −

{ "_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"} ] }
   

In this document, we have included information about the customer who buys the product in the product_bought_by field . Now, when a new customer purchases a product, we first check if the product is available using the product_available field . If available, we'll decrement the product_available field and also insert the new customer's embedded document in the product_bought_by field. We will use the findAndModify command for this functionality because it searches and updates the document at the same time.

> 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" }} } }) 
       

Our inline document approach and use of the findAndModify query ensures that the product purchase information is only updated if the product is available. And this whole transaction, located in one request, is atomic.

In contrast, consider a scenario where we could separately store product availability information and who bought it. In this case, we will first check if the product is available using the first request. Then in the second request, we will update the purchase information. However, it is possible that between these two requests, some other user purchased the product and it is no longer available. Without knowing it, our second request will update the purchase information based on the result of our first request. This will make the database incompatible because we have sold a product that is not available.