AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

トランザクション

MongoDBでは、1 つのドキュメントに対する操作は不可分です。単一ドキュメント構造内でのデータ間の関係をキャプチャするには、複数のドキュメントとコレクションにわたる正規化プロセスを経る代わりに埋め込みドキュメントと配列を利用できるため、マルチドキュメントトランザクションは多数の実用的なユースケースでは不要になります。

複数のドキュメントに対する操作のアトミック性が必要な状況では、 MongoDB はトランザクションをサポートします。複数の操作、コレクション、データベース、ドキュメント、シャードにわたってトランザクションを使用できます。

MongoDB supports ACID transactions. Transactions provide atomicity, consistency, isolation, and durability according to the configured read and write concern settings.

言語セレクターを使用して、次の例の言語を設定します。

Tip

For an example in mongosh, see mongosh Example.

MongoDB は(単一または複数のコレクション内の)複数のドキュメントへの読み取りと書込みにアトミック性を必要とする状況で、レプリカセットやシャーディングされたクラスターでのトランザクションを含む分散トランザクションをサポートします。

分散トランザクションは次のとおりアトミックな性質を持ちます。

  • トランザクションは、データ変更をすべて適用するか、変更をロールバックします。

  • トランザクションがコミットされると、トランザクション内で行われたすべてのデータ変更が保存され、トランザクション外でも表示されます。

    トランザクションがコミットされるまで、トランザクションで行われたデータ変更はトランザクションの外部には表示されません。

    ただし、トランザクションが複数のシャードに書き込む場合、すべての外部読み取り操作が、コミットされたトランザクションの結果がシャード全体で表示されるまで待機する必要はありません。たとえば、トランザクションがコミットされ、書込み 1 がシャード A で表示されているものの、書込み 2 がシャード B にまだ表示されていない場合、読み取り保証(read concern) "local" での外部読み取りは、書き込み 2 を見ることなく書き込み 1 の結果を読み取ることができます。

  • トランザクションが中止されると、トランザクションで行われたすべてのデータの変更は表示されることなく破棄されます。

重要

ほとんどの場合、分散トランザクションでは 1 つのドキュメントの書き込み (write) よりもパフォーマンス コストが高くなります。分散トランザクションの可用性は、効果的なスキーマ設計の代わりにはなりません。多くのシナリオにおいて、非正規化されたデータモデル(埋め込みドキュメントと配列)が引き続きデータやユースケースに最適です。つまり、多くのシナリオにおいて、データを適切にモデリングすることで、分散トランザクションの必要性を最小限に抑えることができます。

トランザクションの使用に関するその他の考慮事項(ランタイム制限や oplog サイズ制限など)については、「本番環境での考慮事項」も参照してください。

トランザクションは、複数の操作、コレクション、データベース、ドキュメント、シャードにわたって使用できます。

トランザクションについて:

  • コレクションとインデックスはトランザクション内で作成できます。詳細については、「トランザクション内でのコレクションとインデックスの作成」を参照してください。

  • トランザクションで使用されるコレクションは、異なるデータベースにある可能性があります。

    注意

    クロスシャードの書き込みトランザクションでは新しいコレクションを作成できません。たとえば、あるシャードで既存コレクションに書き込み、別のシャードで暗示的にコレクションを作成する場合、MongoDB では同じトランザクションで両方の操作を実行できません。

  • Capped コレクションには書き込めません。

  • Capped コレクションから読み取る場合、読み取り保証(read concern)"snapshot" は使用できません。(MongoDB 5.0 以降)

  • config データベース、 admin データベース、または local データベース内のコレクションの読み取りと書き込みはできません。

  • system.* コレクションに書き込み (write) はできません。

  • explain または類似コマンドを使用して、サポートされている操作のクエリプランを返すことはできません。

  • トランザクションの外部で作成されたカーソルの場合、トランザクション内で getMore を呼び出せません。

  • トランザクション内で作成されたカーソルの場合、トランザクション外で getMore を呼び出せません。

  • You cannot specify the killCursors command as the first operation in a transaction. Additionally, if you run the killCursors command within a transaction, the server immediately stops the specified cursors. It does not wait for the transaction to commit.

トランザクションでサポートされない操作のリストについては、「制限付き操作」を参照してください。

Tip

トランザクションを開始する直前にコレクションを作成または削除する際に、トランザクション内のコレクションにアクセスする場合、書込み保証(write concern)付きで "majority" に作成または削除操作を発行して、トランザクションが必要なロックを取得できるようにします。

トランザクションが クロスシャード書込みトランザクション (write transaction)でない場合、トランザクション内で次の操作を実行できます。

  • コレクションを作成する。

  • 同じトランザクション内で以前に作成された新しい空のコレクションにインデックスを作成する

トランザクション内でコレクションを作成する際、以下を実行できます。

トランザクション内でインデックスを作成する場合 [1]、作成するインデックスは次のいずれかに配置される必要があります。

  • 存在しないコレクション。コレクションは、操作中に作成されます。

  • 同じトランザクション内で以前に作成された新しい空のコレクション。

[1] 既存インデックスに対して db.collection.createIndex()db.collection.createIndexes() を実行して、その有無を確認することもできます。これらの操作は、インデックスを作成せずに正常に返されます。
  • クロスシャードの書き込みトランザクションでは新しいコレクションを作成できません。たとえば、あるシャードで既存コレクションに書き込み、別のシャードで暗示的にコレクションを作成する場合、MongoDB では同じトランザクションで両方の操作を実行できません。

  • シャーディングされたコレクションをターゲットにしている間は、トランザクション内で $graphLookup ステージを使用できません

  • トランザクション内でコレクションまたはインデックスを明示的に作成する場合、トランザクションの読み取り保証(read concern)は "local" でなければなりません。

    コレクションとインデックスを明示的に作成するには、次のコマンドとメソッドを使用します。

トランザクション内でカウント操作を実行するには、$count 集計ステージまたは $group$sum式を使用) 集計ステージを使用します。

MongoDB ドライバーは、$group$sum 式を併用してカウントを実行するヘルパー メソッドとして、コレクションレベルの API countDocuments(filter, options)を提供します。

mongosh provides the db.collection.countDocuments() helper method that uses the $group with a $sum expression to perform a count.

トランザクション内で個別の操作を実行するには、以下を使用できます。

  • シャーディングされていないコレクションの場合、db.collection.distinct() メソッドまたは distinct コマンド、および 集計パイプラインを $group ステージと併用できます。

  • シャーディングされたコレクションの場合、db.collection.distinct() メソッド、または distinct コマンドは使用できません。

    シャーディングされたコレクションの個別の値を検索するには、代わりに $group ステージで集計パイプラインを使用します。以下に例を挙げます。

    • db.coll.distinct("x") の代わりに以下を使用します

      db.coll.aggregate([
      { $group: { _id: null, distinctValues: { $addToSet: "$x" } } },
      { $project: { _id: 0 } }
      ])
    • db.coll.distinct("x", { status: "A" }) の代わりに以下を使用します。

      db.coll.aggregate([
      { $match: { status: "A" } },
      { $group: { _id: null, distinctValues: { $addToSet: "$x" } } },
      { $project: { _id: 0 } }
      ])

    パイプラインはドキュメントにカーソルを返します。

    { "distinctValues" : [ 2, 3, 1 ] }

    カーソルを反復して、結果ドキュメントにアクセスします。

情報提供コマンドには、hellobuildInfoconnectionStatus(およびこれらのヘルパー メソッド)などがあり、トランザクションに含めることができますが、最初の操作になることはできません。

次の操作はトランザクションでは許可されません。

  • クロスシャードの書き込みトランザクションで新しいコレクションを作成します。たとえば、あるシャードで既存コレクションに書き込み、別のシャードで暗示的にコレクションを作成する場合、MongoDB では同じトランザクションで両方の操作を実行できません。

  • コレクションの明示的な作成db.createCollection()メソッドやインデックスの明示的な作成(db.collection.createIndexes() および db.collection.createIndex() メソッドなど)で、"local" 以外の読み取り保証(read concern)レベルを使用する場合

  • listCollections コマンドと listIndexes コマンド、およびそのヘルパー メソッド。

  • その他の CRUD 操作や情報操作以外の操作、例えば createUsergetParametercount などおよびその補助ツール。

  • トランザクションはセッションに関連付けられます。

  • 1 セッションで一度に開くことができるトランザクションは 1 つまでです。

  • ドライバーを使用する場合、トランザクション内の各操作はセッションに関連付けられる必要があります。詳細については、ドライバー固有のドキュメントを参照してください。

  • セッションが終了し、そのセッションにオープン トランザクションがある場合、そのトランザクションは中止されます。

トランザクション内の操作では、トランザクションレベルの読み込み設定(read preference)が使用されます。

ドライバーを使用すると、トランザクション開始時にトランザクションレベルの読み込み設定(read preference)を設定できます。

  • 読み込み設定(read preference)がトランザクションレベルで設定されていない場合、セッションレベルの読み込み設定がトランザクションで使用されます。

  • 読み込み設定(read preference)がトランザクションとセッションのいずれのレベルでも設定されていない場合、クライアントレベルの読み込み設定がトランザクションで使用されます。デフォルトでは、クライアントレベルの読み込み設定が primary となります。

Transactions that contain read operations must use read preference primary. All operations in a given transaction must route to the same member.

トランザクション内の操作では、トランザクションレベルの読み取り保証(read concern)が使用されます。つまり、コレクションレベルとデータベースレベルで設定された読み取り保証は、トランザクション内では無視されます。

トランザクションの開始時に、トランザクションレベルの読み取り保証(read concern)を設定できます。

  • トランザクションレベルの読み取り保証(read concern)の設定が解除されている場合、トランザクションレベルの読み取り保証はデフォルトでセッションレベルの読み取り保証になります。

  • トランザクションレベルとセッションレベルの読み取り保証(read concern)の設定が解除されている場合、トランザクションレベルの読み取り保証はデフォルトでクライアントレベルの読み取り保証に設定されます。デフォルトでは、クライアントレベルの読み取り保証は プライマリでの読み取りで "local" となります。以下も参照してください。

トランザクションは次の読み取り保証(read concern)レベルをサポートします。

  • 読み取り保証(read concern)"local" は、ノードから入手可能な最新データを返しますが、ロールバックも可能です。

  • レプリカセットでは、トランザクションが読み取り保証localを使用している場合でも、トランザクションが開かれた時点でのスナップショットから操作が読み取られる場合、より強力な読み取り分離が見られる可能性があります。

  • For transactions on sharded cluster, "local" read concern cannot guarantee that the data is from the same snapshot view across the shards. If snapshot isolation is required, use "snapshot" read concern.

  • You can create collections and indexes inside a transaction. If explicitly creating a collection or an index, the transaction must use read concern "local". If you implicitly create a collection, you can use any of the read concerns available for transactions.

  • If the transaction commits with write concern "majority", read concern "majority" returns data that has been acknowledged by a majority of the replica set members and can't be rolled back. Otherwise, read concern "majority" provides no guarantees that read operations read majority-committed data.

  • For transactions on sharded cluster, read concern "majority" can't guarantee that the data is from the same snapshot view across the shards. If snapshot isolation is required, use read concern "snapshot".

  • Read concern "snapshot" returns data from a snapshot of majority committed data if the transaction commits with write concern "majority".

  • If the transaction does not use write concern "majority" for the commit, the "snapshot" read concern provides no guarantee that read operations used a snapshot of majority-committed data.

  • シャーディングされたクラスター上のトランザクションの場合、データの "snapshot" ビューはシャード間で同期されます

トランザクションは、トランザクションレベルの書込み保証 (write concern)を使用して書込み操作をコミットします。トランザクション内の書込み操作は、明示的な書込み保証 (write concern)保証を指定せずに、デフォルトの書込み保証 (write concern)を使用して実行される必要があります。コミット時に、書込み操作はトランザクションレベルの書込み保証 (write concern)を使用してコミットされます。

Tip

トランザクション内の個々の書込み操作に書込み保証(write concern)を明示的に設定しないでください。トランザクション内の個々の書込み操作に書込み保証を設定すると、エラーが返されます。

トランザクションの開始時に、トランザクションレベルの書込み保証(write concern)を設定できます。

  • トランザクションレベルの書込み保証(write concern)の設定が解除されている場合、トランザクションレベルの書込み保証はデフォルトでセッションレベルの書込み保証でコミットされます。

  • トランザクションレベルとセッションレベルのいずれでも書込み保証(write concern)の設定が解除されている場合、トランザクションレベルの書込み保証はデフォルトでクライアントレベルの書込み保証になります。

トランザクションは、以下を含むすべての書込み保証(write concern)の w 値をサポートします。

  • 書込み保証(write concern)w: 1 は、コミットがプライマリに適用された後に確認応答を返します。

    重要

    w: 1 でコミットする場合、トランザクションはフェイルオーバーが発生した場合にロールバック可能です。

  • w: 1 書込み保証(write concern)でコミットする場合、トランザクションレベルの "majority" 読み取り保証(read concern)では、トランザクション内の読み取り操作が過半数でコミットされたデータを読み取るという保証は ありません

  • w: 1 書込み保証(write concern)でコミットする場合、トランザクションレベルの "snapshot" 読み取り保証(read concern)では、トランザクション内の読み取り操作で過半数でコミットされたデータのスナップショットが使用されるという保証は ありません

  • w: "majority" の書込み保証(write concern)は、コミットが投票ノードの過半数に適用された後に確認応答を返します。

  • w: "majority" 書込み保証(write concern) でコミットする場合、トランザクションレベルの "majority" 読み取り保証(read concern)により、操作によって過半数でコミットされたデータが読み取られたことが保証されます。シャーディングされたクラスター上のトランザクションでは、コミットされた過半数のデータのこのビューはシャード間で同期されません。

  • w: "majority" 書込み保証(write concern)でコミットする場合、トランザクションレベルの "snapshot" 読み取り保証(read concern)により、操作によって過半数でコミットされたデータの同期されたスナップショットから読み取られたことが保証されます。

注意

Regardless of the write concern specified for the transaction, the commit operation for a sharded cluster transaction includes some parts that use {w: "majority", j: true} write concern.

サーバー パラメーター coordinateCommitReturnImmediatelyAfterPersistingDecision は、トランザクションをコミットする決定がクライアントに返されるタイミングを制御します。

このパラメーターは MongDB 5.0 で導入されたもので、デフォルト値はtrue です。MongoDB 6.1 ではデフォルト値が false に変更されています。

coordinateCommitReturnImmediatelyAfterPersistingDecisionfalse の場合、 シャードトランザクションの調整役は、トランザクションのコミットの決定をクライアントに返す前に、すべてのノードがトランザクションのコミットを確認するまで待機します。

"majority" 書き込みに対して書込み保証 (write concern)を指定し、かつ操作が応答を返す前に 計算された過半数レプリカセット ノードに複製されない場合、データは最終的に複製またはロールバックされます。wtimeout を参照してください。

Regardless of the write concern specified for the transaction, the driver applies w: "majority" as the write concern when retrying commitTransaction.

以下のセクションでは、デプロイメントタイプ、ストレージエンジン、およびMongoDB のバージョンによって異なるトランザクションの要件と考慮事項について説明します。

本番環境でのトランザクションについては、「本番環境での考慮事項」を参照してください。シャーディングされたクラスターについては、「本番環境での考慮事項(シャーディングされたクラスター)」も参照してください。

レプリカセットにアービタがある場合、トランザクションを使用してシャードキーを変更することはできません。 アービタは、 マルチシャード トランザクションに必要なデータ操作に参加することはできません。

書込み操作が複数のシャードにまたがるトランザクションで、アービタを含むシャードを対象に読み取りまたは書込み操作が実行される場合、そのトランザクションはエラーとなり中止します。

シャーディングされたクラスターのうち writeConcernMajorityJournalDefaultfalse に設定されているもの(インメモリ ストレージエンジンを使用する投票ノードのあるシャードなど)ではトランザクションを実行できません。

注意

Regardless of the write concern specified for the transaction, the commit operation for a sharded cluster transaction includes some parts that use {w: "majority", j: true} write concern.

トランザクションのステータスとメトリクスを取得するには、次のメソッドを使用します。

ソース
戻り値

トランザクション メトリクスを返します。

MongoDB Atlas無料クラスターまたは Flex クラスターでは、一部の serverStatus 応答フィールドは返されません。詳細については、MongoDB Atlasドキュメントの「制限されたコマンド」を参照してください。

$currentOp 集計パイプライン

次の値を返します。

次の値を返します。

mongod および mongos のログ メッセージ

低速(operationProfiling.slowOpThresholdMs のしきい値を超える)トランザクションに関する情報を TXN ログ コンポーネントに含めます。

トランザクションを使用するには、配置のすべてのノードの FeatureCompatibilityVersion が次のバージョン以上である必要があります。

配置
最小 featureCompatibilityVersion

レプリカセット

4.0

シャーディングされたクラスター

4.2

ノードの機能の互換性バージョンを確認するには、該当ノードに接続して次のコマンドを実行します。

db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )

詳細については、setFeatureCompatibilityVersion に関する参考ページを参照してください。

トランザクションは、次のレプリカセットとシャーディングされたクラスターでサポートされます。

  • プライマリが WiredTiger ストレージエンジンを使用しており、かつ

  • セカンダリ ノードが、WiredTiger ストレージエンジンまたはインメモリ ストレージエンジンのいずれかを使用している。

注意

シャーディングされたクラスターのうち writeConcernMajorityJournalDefaultfalse に設定されているもの(インメモリ ストレージエンジンを使用する投票ノードのあるシャードなど)ではトランザクションを実行できません。

MongoDB 5.2 以降(および 5.0.4で)、以下の項目が適用されます。

  • クエリがシャードにアクセスしたときに、チャンク移行または DDL 操作によってコレクションのクリティカル セクションが保持されている可能性があります。

  • トランザクション内のクリティカル セクションをシャードが待機する時間を制限するには、metadataRefreshInTransactionMaxWaitBehindCritSecMS パラメーターを使用します。