English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
原子性を維持するための推奨方法は、関連するすべての情報を保持し、それらを埋め込まれたドキュメントとして1つのドキュメントに更新することです。これにより、1つのドキュメントのすべての更新が原子的に保証されます。
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 クエリを使用して、製品が利用可能な場合のみ製品の購入情報を更新することを確実にしています。このトランザクション全体は同じクエリ内で、原子的に行われます。
これとは逆に、以下のような状況を考えてみてください:私たちは製品の利用可能性与誰がその製品を購入したかの情報をそれぞれ保持しています。この場合、まず製品が利用可能かどうかを確認するために最初のクエリを使用します。次に、購入情報を更新するために第2つのクエリを使用します。しかし、この2つのクエリを実行する間に他のユーザーがその製品を購入して、その製品が利用不可能になる可能性があります。そのことを知らない場合、私たちの第2つのクエリは最初のクエリの結果に基づいて購入情報を更新します。これにより、データベースが一致しなくなり、私たちは利用不可能な製品を販売してしまうことになります。