MongoDB原子操作
MongoDB 不支持多文檔原子事務。 但是,它確實提供了原子操作在一個單一的文檔。因此,如果文檔有上百個字段,更新語句要麼更新所有字段或不更新所有,因此保持原子在文檔級彆。
原子操作模型數據
推薦的方法,以保持原子將保留所有的相關信息,這些信息經常更新,一個文檔中使用嵌入文檔。這將確保所有的更新為一個單一文檔是原子。
考慮下麵的 products 文檔:
{ "_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" } ] }
在本文檔中,我們已經嵌入客戶買該產品的信息在 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:"rob",date:"9-Jan-2014"}} } })
嵌入式文檔並使用 findAndModify 查詢的方法可以確保隻有當它是提供產品的購買信息時被更新。 而整個此事務在同一個查詢中的,所以是一個原子的。
與此相反,考慮我們可能已經保存了產品的可用性和已經購買的產品,獨立的信息情形。在這種情況下,我們會先檢查該產品先查詢是否可用。第二個查詢,我們將更新采購信息。然而,這是可能的,這兩個查詢的執行之間,其他一些用戶已經購買的產品,它冇有更多可用。如果不知道這一點,我們的第二個查詢將更新基於第一個查詢結果的購買信息。這將使數據庫不一致,因為我們銷售的產品是不具備(產品可能冇有了)的。