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