MongoDB原子操作

MongoDB不支持多文檔原子事務。 但是,它可以爲單個文檔提供了原子操作。 因此,如果文檔有一百個字段,則更新語句將更新或不更新所有字段的值,因此在原始級別保持原子性。

原子操作模型數據

維持原子性的推薦方法是將所有相關信息保存在一起,並使用嵌入式文檔在一個文檔中一起更新。 這將確保單個文檔的所有更新都是原子的。

考慮以下產品文件 -

{
   "_id":1,
   "product_name": "Huawei P9",
   "category": "mobiles",
   "product_total": 5,
   "product_available": 3,
   "product_bought_by": [
      {
         "customer": "Kobe",
         "date": "2017-07-08"
      },
      {
         "customer": "Maxsu",
         "date": "2018-07-28"
      }
   ]
}

在上面這個文檔中,已經在product_bought_by字段中嵌入了購買產品的客戶的信息。 現在,當有新客戶購買產品,首先查看product_available字段檢查產品存貨是否仍然夠用。

如果可用,則減少product_available字段的值,並將新客戶的嵌入式文檔插入到product_bought_by字段中。下面將使用findAndModify命令來執行此功能,因爲它會以同樣的方式搜索和更新文檔。

>db.products.findAndModify({ 
   query:{_id:2,product_available:{$gt:0}}, 
   update:{ 
      $inc:{product_available:-1}, 
      $push:{product_bought_by:{customer:"Curry",date:"2017-08-08"}} 
   }    
})

嵌入式文檔和使用findAndModify查詢的方法確保產品購買信息僅在產品可用時才更新。 而整個這個事務在同一個查詢中是原子的。

與此相反的是如果分別保留產品數量,以及誰購買產品的信息。在這種情況下,我們將首先使用第一個查詢檢查產品是否可用。然後在第二個查詢中更新購買信息。 但是,有可能在執行這兩個查詢時(還未執行完),其他一些用戶已經購買了該產品,並且此產品缺貨了。但是由於程序執行過程中並不知曉,第二個查詢將根據第一個查詢的結果更新購買信息。這會導致數據庫不一致,因爲產品已經沒有庫存,但是仍然斷續銷售。