トランザクションによるデータ整合性の強制
トランザクションを使用して、重複データを含むコレクション間で整合性を強制できます。 トランザクションは、1 回のアトミック操作で複数のコレクションを更新します。
アプリケーションが常に最新のデータを返す必要があり、頻繁に読み取りを行った期間中にパフォーマンスに悪影響が及ぶ可能性がある場合は、 トランザクション を使用して整合性を強制します。
データ整合性を強制する他の方法と比べて、トランザクションのパフォーマンスが低下する可能性があります。 トランザクションが開いている間は、読み取りパフォーマンスに悪影響が及ぶ可能性があります。 ただし、トランザクションにより、クライアントが読み込むデータは常に最新の状態に保たれます。
このタスクについて
トランザクションを使用するには、 レプリカセット または シャーディングされたクラスター に接続する必要があります。 スタンドアロン配置ではトランザクションを使用できません。
始める前に
データの整合性を強制する のさまざまな方法を検討して、トランザクションがアプリケーションに最適なアプローチであることを確認します。 詳細については、「データの整合性 」を参照してください。
手順
次の例では、eコマース アプリケーションでデータの整合性を強制します。 サンプル スキーマでは、 products
とsellers
コレクション内の製品情報を重複させます。 このスキーマ設計は、製品と販売者の両方のクエリを最適化します。
価格が変更された場合など、製品がアップデートされる場合、products
sellers
コレクションと コレクションで価格が一貫していることが重要です。したがって、 トランザクション は、このアプリケーションでデータの整合性を強制するのに適した方法です。
サーバー コレクションの作成
use test db.sellers.insertOne( { id: 456, name: "Cool Clothes Co", location: { address: "21643 Andreane Shores", state: "Ohio", country: "United States" }, phone: "567-555-0105", products: [ { name: "sweater", price: 30 }, { name: "t-shirt", price: 10 }, { name: "vest", price: 20 } ] } )
更新を処理するためのトランザクションの構成
注意
次の例では、 mongosh
のトランザクションを使用しています。 MongoDB ドライバーのトランザクションの例については、「トランザクション 」を参照してください。
次の例では、トランザクションを使用して、 コレクションとvest
products
コレクションの両方内のsellers
の価格を更新します。
// Start a session session = db.getMongo().startSession( { readPreference: { mode: "primary" } } ); productsCollection = session.getDatabase("test").products; sellersCollection = session.getDatabase("test").sellers; // Start a transaction session.startTransaction( { readConcern: { level: "local" }, writeConcern: { w: "majority" } } ); // Operations inside the transaction try { productsCollection.updateOne( { sellerId: 456, name: "vest" }, { $set: { price: 25 } } ); sellersCollection.updateOne( { }, { $set: { "products.$[element].price": 25 } }, { arrayFilters: [ { "element.name": "vest" } ] } ); } catch (error) { // Cancel transaction on error session.abortTransaction(); throw error; } // Commit the transaction using write concern set at transaction start session.commitTransaction(); session.endSession();
結果
価格が更新されたこととデータの整合性があることを確認するには、products
sellers
コレクションと コレクションをクエリします。
製品コレクションのクエリ
db.products.find( { sellerId: 456, name: "vest" } )
出力:
[ { _id: ObjectId("64d506c3ddebf45734d06c58"), sellerId: 456, name: 'vest', price: 25, rating: 4.7 } ]
販売者コレクションをクエリする
db.sellers.find( { id: 456, "products.name": "vest" } )
出力:
[ { _id: ObjectId("64d516d9ddebf45734d06c5a"), id: 456, name: 'Cool Clothes Co', location: { address: '21643 Andreane Shores', state: 'Ohio', country: 'United States' }, phone: '567-555-0105', products: [ { name: 'sweater', price: 30 }, { name: 't-shirt', price: 10 }, { name: 'vest', price: 25 } ] } ]
詳細
データの整合性を強制する他の方法については、次を参照してください。