English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Одним из методов поддержания атомарности является сохранение всех связанных данных, которые часто обновляются вместе с внедренными документами в один документ. Это гарантирует, что все обновления в одном документе будут атомарными.
Предположим, что我们已经 создали коллекцию под названием 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, чтобы обеспечить обновление информации о покупке продукта только при условии, что продукт доступен. Вся транзакция выполняется в одном запросе и является атомарной.
Напротив, рассмотрим следующую ситуацию: мы можем хранить информацию о доступности продукта и о том, кто его купил. В этом случае мы сначала проверим доступность продукта с помощью первой запроса. Затем в втором запросе мы обновим информацию о покупке. Однако, возможно, что между выполнением этих двух запросов другой пользователь купил этот продукт, и он больше не доступен. Не зная этого, наш второй запрос обновит информацию о покупке на основе результата первого запроса. Это приведет к несоответствию базы данных,因为我们 уже продали недоступный продукт.