原子性とトランザクション
アトミック性
MongoDB での書込み操作は、単一のドキュメント内の 複数の埋め込みドキュメントを変更する場合でも、単一のドキュメント レベルでアトミックです。
マルチドキュメントトランザクション
単一の書き込み操作(例: db.collection.updateMany()
) は複数のドキュメントを変更します。各ドキュメントの変更はアトミックですが、操作全体はアトミックではありません。
複数のドキュメントへの書込み操作を実行する場合、1 回の書込み操作でも複数の書込み操作でも、他の操作がインターリーブすることがあります。
MongoDB は(単一または複数のコレクション内の)複数のドキュメントへの読み取りと書込みにアトミック性を必要とする状況で、レプリカセットやシャーディングされたクラスターでのトランザクションを含む分散トランザクションをサポートします。
詳細についてはトランザクションを参照してください。
重要
ほとんどの場合、分散トランザクションでは 1 つのドキュメントの書き込み (write) よりもパフォーマンス コストが高くなります。分散トランザクションの可用性は、効果的なスキーマ設計の代わりにはなりません。多くのシナリオにおいて、非正規化されたデータモデル(埋め込みドキュメントと配列)が引き続きデータやユースケースに最適です。つまり、多くのシナリオにおいて、データを適切にモデリングすることで、分散トランザクションの必要性を最小限に抑えることができます。
トランザクションの使用に関するその他の考慮事項(ランタイム制限や oplog サイズ制限など)については、「本番環境での考慮事項」も参照してください。
同時実行制御
同時実行制御により、データの不整合や競合を引き起こすことなく、複数のアプリケーションを同時に実行できます。
ドキュメントに対する findAndModify
操作はアトミックです。つまり、検索条件がドキュメントと一致すると、そのドキュメントに対してアップデートが実行されます。そのドキュメントで同時に実行されているクエリや追加のアップデートは、現在のアップデートが完了するまで影響を受けません。
次の例で考えてみます。
次の 2 つのドキュメントを含むコレクション。
db.myCollection.insertMany( [ { _id: 0, a: 1, b: 1 }, { _id: 1, a: 1, b: 1 } ] ) 次の
findAndModify
操作のうち 2 つが同時に実行されます。db.myCollection.findAndModify( { query: { a: 1 }, update: { $inc: { b: 1 }, $set: { a: 2 } } } )
findAndModify
操作が完了すると、両方のドキュメントの a
と b
が2
に設定されることが保証されます。
また、フィールドにユニークインデックスを作成して、ユニークな値のみを含めるようにすることもできます。これにより、挿入や更新によって重複データが作成されるのを防ぎます。複数のフィールドにユニークインデックスを作成して、フィールド値の組み合わせを確実にユニークにすることができます。例については、 ユニークインデックスを使用した findAndModify() のアップサートを参照してください。