MongoDB 原子操作

mongodb不支持事务,所以,在你的项目中应用时,要注意这点。无论什么设计,都不要要求mongodb保证数据的完整性。

但是mongodb提供了许多原子操作,比如文档的保存,修改,删除等,都是原子操作。

所谓原子操作就是要么这个文档保存到Mongodb,要么没有保存到Mongodb,不会出现查询到的文档没有保存完整的情况。

原子操作的模型数据

维持原子性的推荐方法是保留所有相关信息,这些信息经常使用嵌入式文档在单个文档中一起更新。这将确保单个文档的所有更新都是原子的。

假设我们已经创建了一个名为 productDetails 的集合并在其中插入了一个文档,如下所示

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

在本文档中,我们在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 查询确保产品购买信息仅在产品可用时更新。并且整个事务都在同一个查询中,是原子的。

与此相反,请考虑我们可能单独保留产品可用性和有关谁购买了产品的信息的场景。在这种情况下,我们将首先使用第一个查询检查产品是否可用。然后在第二个查询中我们将更新购买信息。但是,在执行这两个查询之间,可能有其他用户购买了该产品并且不再可用。在不知道这一点的情况下,我们的第二个查询将根据第一个查询的结果更新购买信息。这将导致数据库不一致,因为我们销售的产品不可用。

查看笔记

扫码一下
查看教程更方便