翻译或纠错本页面

原子性事务建模

On this page

范式

MongoDB的一些写操作如 db.collection.update(), db.collection.findAndModify(), db.collection.remove() 等 具有文档级的事务原子性。对于必须同时修改的字段,把这些字段通过建模放在同一个文档内可以保证这些字段更新的原子性: 要么全部修改,要么一个都不修改。

举例来说,假设你在设计一个图书馆的借书系统,你需要管理书的库存量以及出借记录。

一本书的可借数量加上借出数量的和必须等于总的保有量,那么对这两个字段的更新必须是原子性的。把 availablecheckout 两个字段放到同一个文档里,就可以做到对这两个字段的原子性事务。

{
    _id: 123456789,
    title: "MongoDB: The Definitive Guide",
    author: [ "Kristina Chodorow", "Mike Dirolf" ],
    published_date: ISODate("2010-09-24"),
    pages: 216,
    language: "English",
    publisher_id: "oreilly",
    available: 3,
    checkout: [ { by: "joe", date: ISODate("2012-10-15") } ]
}

在更新出借记录的时候,你可以用 db.collection.update() 的方法来对 availablecheckout 两个字段同时更新:

db.books.update (
   { _id: 123456789, available: { $gt: 0 } },
   {
     $inc: { available: -1 },
     $push: { checkout: { by: "abc", date: new Date() } }
   }
)

这个操作会返回一个包含操作结果信息的 WriteResult() 对象:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

其中 nMatched 字段表示 1 个文档匹配指定的条件。 nModified 字段表示 1 个文档被更新。

If no document matched the update condition, then nMatched and nModified would be 0 and would indicate that you could not check out the book.