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 查询的方法确保了,只有当产品还有足够数量时,才更新产品购买信息。在整个过程中,同一查询中的事务是原子性的。
与之相反的情况是,我们可能会想分别保持产品可用性与购买产品的顾客信息。在这种情况下,我们会首先使用第一个查询来检查产品是否够用。然后在第二个查询中更新购买信息。但在这两个查询的执行过程之间,其他一些顾客也可能会购买了产品,从而使产品变得不够用了。由于没有了解到这种情况,我们的第二个查询根据第一个查询的结果进行了更新。这将造成数据库的不一致性。
感觉本站内容不错,读后有收获?小额赞助,鼓励网站分享出更好的教程