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查詢的方法確保產品購買資訊僅在產品可用時才更新。 而整個這個事務在同一個查詢中是原子的。

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