MongoDB 基础教程

MongoDB 高级教程

MongoDB 笔记

original icon
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.knowledgedict.com/tutorial/mongodb-atomic-operations.html

MongoDB 原子操作


MongoDB 并不支持多文档原子事务(multi-document atomic transactions)。但它提供了针对单个文档的原子操作。假如一个文档包含数百个字段,则 update 语句将更新所有的字段,或者一个也不更新,从而维持了文档级的原子性。

原子操作数据模型

维持原子性的建议方法是利用内嵌文档(embedded 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"
      }
   ]
}

在这个文档中,将购买产品的顾客的信息内嵌在 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 查询的方法确保了,只有当产品还有足够数量时,才更新产品购买信息。在整个过程中,同一查询中的事务是原子性的。

与之相反的情况是,我们可能会想分别保持产品可用性与购买产品的顾客信息。在这种情况下,我们会首先使用第一个查询来检查产品是否够用。然后在第二个查询中更新购买信息。但在这两个查询的执行过程之间,其他一些顾客也可能会购买了产品,从而使产品变得不够用了。由于没有了解到这种情况,我们的第二个查询根据第一个查询的结果进行了更新。这将造成数据库的不一致性。