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

トランザクションを使用するバッチ変更

このガイドでは、EF Core Provider アプリケーションでトランザクションを使用する方法を学ぶことができます。トランザクションは一連の書き込み操作をラップします。トランザクション内の操作が 1 つでも失敗すると、プロバイダーはトランザクション内のすべての変更をロールバックします。この動作により、データの整合性が確保されます。

EF Core プロバイダーは次のトランザクション モードをサポートしています。

  • 暗黙的なトランザクション: プロバイダーは、SaveChanges() メソッドと SaveChangesAsync() メソッドへの呼び出しを自動的にトランザクションでラップします。この動作を構成または無効にする方法については、暗黙的なトランザクションの構成を参照してください。

  • 明示的なトランザクション: Database.BeginTransaction() メソッドを呼び出してトランザクションを手動で開始し、Commit() または Rollback() を呼び出してトランザクションをコミットまたはロールバックします。

このガイドの例では、 sample_guidesデータベースの planetsコレクションを使用します。このコレクションのドキュメントは、次の Planetクラスをモデルとして使用します。

public class Planet
{
public ObjectId _id { get; set; }
public string name { get; set; } = null!;
public int orderFromSun { get; set; }
public bool hasRings { get; set; }
}

このコレクションは、サンプルデータセットから構成されています。無料のMongoDBクラスターを作成し、このサンプルデータをロードする方法については、クイックスタートガイドを参照してください。

トランザクションを使用する前に、以下の要件と制約事項に留意してください。

  • トランザクションには、レプリカセットやシャーディングされたクラスターなどのマルチドキュメントトランザクションをサポートするMongoDB Server の配置が必要です。アプリケーションがスタンドアロン配置でトランザクションを開始しようとすると、プロバイダーは NotSupportedException をスローします。これを防ぐには、暗黙的トランザクションの構成に記述されているように AutoTransactionBehavior.Never を設定します。

  • EF Core プロバイダーは、System.Transactions.TransactionScopeによって作成されるような .NET 環境トランザクションをサポートしません。環境トランザクションを使用しようとすると、プロバイダーは例外をスローします。代わりに暗黙的または明示的なトランザクションを使用します。

デフォルトで、EF Core プロバイダーは複数の ルート エンティティ が影響を受ける場合、SaveChanges()SaveChangesAsync() の呼び出しを自動的にトランザクションでラップします。ルート エンティティは、コレクション内のトップレベル ドキュメントです。これは、別のドキュメント内に保存される所有型または埋め込み型とは対照的です。

次の例では、単一の SaveChanges() 呼び出しで 2 つの惑星を挿入しています。この操作は複数のルートエンティティに影響するため、プロバイダーは自動的にトランザクションでラップします。いずれかの挿入が失敗した場合、プロバイダーは両方の変更をロールバックします。

SynchronousAsynchronous対応するコードを表示するには、 タブまたは タブを選択します。

dbContext.Planets.AddRange(
new Planet { Name = "Mercury" },
new Planet { Name = "Venus" }
);
// Both inserts succeed or both are rolled back
dbContext.SaveChanges();
dbContext.Planets.AddRange(
new Planet { Name = "Mercury" },
new Planet { Name = "Venus" }
);
// Both inserts succeed or both are rolled back
await dbContext.SaveChangesAsync();

DbContextオブジェクトのDatabase.AutoTransactionBehaviorプロパティは、プロバイダーが暗黙的なトランザクションを使用するタイミングを制御します。このプロパティは、AutoTransactionBehavior列挙から値を受け入れます。これには次の値が含まれます。

説明

WhenNeeded

プロバイダーは、SaveChanges()またはSaveChangesAsync()が複数のルート エンティティに影響する場合にのみトランザクションを使用します。これがデフォルト値です。

Always

プロバイダーは、単一エンティティ操作ですら、常にトランザクションを使用します。

Never

プロバイダーはトランザクションを使用しません。

次の例に示すように、SaveChanges() または SaveChangesAsync() メソッドを呼び出す前に、いつでもこのプロパティを設定できます。対応するコードを表示するには、Synchronous タブまたは Asynchronous タブを選択します。

dbContext.Database.AutoTransactionBehavior = AutoTransactionBehavior.Never;
// This SaveChanges() call will not use a transaction
dbContext.Planets.Add(new Planet { Name = "Mars" });
dbContext.SaveChanges();
dbContext.Database.AutoTransactionBehavior = AutoTransactionBehavior.Never;
// This SaveChangesAsync() call will not use a transaction
dbContext.Planets.Add(new Planet { Name = "Mars" });
await dbContext.SaveChangesAsync();

明示的なトランザクションを使用して、複数の SaveChanges() 呼び出しとその他の操作を 1 つのアトミックな作業単位にグループ化できます。明示的なトランザクションを開始するには、Database.BeginTransaction() または Database.BeginTransactionAsync() メソッドを呼び出します。操作を実行した後、Commit() または CommitAsync() を呼び出してトランザクションを完了します。

次の例では、複数の操作を 1 つのトランザクションにまとめることで、このパターンを示しています。いずれかの操作で例外がスローされた場合、プロバイダーはトランザクション内のすべての変更を自動的にロールバックします。SynchronousAsynchronous対応するコードを表示するには、 タブまたは タブを選択します。

using var transaction = dbContext.Database.BeginTransaction();
var planet = dbContext.Planets.First(p => p.Name == "Mercury");
planet.Name = "Mercury (Updated)";
dbContext.SaveChanges();
dbContext.Planets.Add(new Planet { Name = "Venus" });
dbContext.SaveChanges();
transaction.Commit();
await using var transaction = await dbContext.Database.BeginTransactionAsync();
var planet = await dbContext.Planets.FirstAsync(p => p.Name == "Mercury");
planet.Name = "Mercury (Updated)";
await dbContext.SaveChangesAsync();
dbContext.Planets.Add(new Planet { Name = "Venus" });
await dbContext.SaveChangesAsync();
await transaction.CommitAsync();

Tip

マニュアルなロールバック

このページの例では、using 宣言を使用してトランザクションを自動的にロールバックし、トランザクション オブジェクトを破棄します。トランザクションを手動でロールバックするには、catch ブロックで Rollback() または RollbackAsync() メソッドを呼び出します。

BeginTransaction() または BeginTransactionAsync() メソッドに TransactionOptions オブジェクトを渡すと、トランザクションの読み取り保証 (read concern)、書込み保証 (write concern)、読み込み設定 (read preference)、および最大コミット時間を構成できます。

TransactionOptionsクラスには次のプロパティがあります。

プロパティ
タイプ
説明

ReadConcern

ReadConcern

トランザクション内の最初のコマンドに対する読み取り保証 (read concern)。デフォルト値は null です。このプロパティを設定しない場合、プロバイダーはセッションのデフォルトトランザクションオプションまたは MongoClient から値を継承します。

ReadPreference

ReadPreference

トランザクション内の読み取り操作の読み込み設定 (read preference)。トランザクションはプライマリから読み取る必要があります。デフォルト値は null です。このプロパティを設定しない場合、プロバイダーはセッションのデフォルトのトランザクション オプションまたは MongoClient から値を継承します。

WriteConcern

WriteConcern

commitTransaction コマンドと abortTransaction コマンドの書込み保証。デフォルト値は null です。このプロパティを設定しない場合、プロバイダーはセッションのデフォルト トランザクション オプションまたは MongoClient から値を継承します。

MaxCommitTime

TimeSpan?

1 つの commitTransaction コマンドの実行を許可する最大時間。デフォルトは null です。このプロパティを設定しない場合、プロバイダーはコミット時間制限を送信しません。

次の例では、ReadConcernMajority を使用してトランザクションを開始します。対応するコードを表示するには、Synchronous タブまたは Asynchronous タブを選択します。

var options = new TransactionOptions(
readConcern: new Optional<ReadConcern>(ReadConcern.Majority)
);
using var transaction = dbContext.Database.BeginTransaction(options);
var planet = dbContext.Planets.First(p => p.Name == "Mercury");
planet.Name = "Mercury (Updated)";
dbContext.SaveChanges();
transaction.Commit();
var options = new TransactionOptions(
readConcern: new Optional<ReadConcern>(ReadConcern.Majority)
);
await using var transaction = await dbContext.Database.BeginTransactionAsync(options);
var planet = await dbContext.Planets.FirstAsync(p => p.Name == "Mercury");
planet.Name = "Mercury (Updated)";
await dbContext.SaveChangesAsync();
await transaction.CommitAsync();

読み取り保証 (read concern)、書込み保証 (write concern)、読み込み設定 (read preference)の詳細については、「読み取り保証 (read concern)」、「書込み保証 (write concern)」、「読み込み設定 (read preference)」を参照してください。

トランザクションを使用する場合、次の制限と注意事項が適用されます。

  • 自動トランザクションは、配置がサポートしていない場合にのみ無効にしてください。自動トランザクションを無効にすると、データの不整合が発生し、楽観的同時実行を使用できなくなります。

  • MongoDB Server はネストされたトランザクションをサポートしません。トランザクションが既にアクティブな状態で BeginTransaction() または BeginTransactionAsync() を呼び出すと、プロバイダーは InvalidOperationException をスローします。

  • MongoDB Server はトランザクションの保存ポイントをサポートしません。トランザクション全体をコミットまたはロールバックする必要があります。

  • デフォルトでは、MongoDB Server は transactionLifetimeLimitSeconds サーバー パラメーターによって制御されるように、60 秒を超えて実行されるトランザクションを中止します。この制限は、暗黙的なトランザクションと明示的なトランザクションの両方に適用されます。トランザクションがこの時間制限を超えると、MongoDB Server はトランザクションを中止し、プロバイダーはエラーをスローします。外部 API 呼び出しなどの時間のかかる操作は、トランザクション内で行わないでください。

  • MongoDB Server でネットワーク中断が発生した場合、またはレプリカセットの選挙を実行する必要がある場合、TransientTransactionError エラーが返される可能性があります。このような場合、EF Core Provider はトランザクションを自動的に再試行しません。一時的なトランザクション エラーと再試行戦略の詳細については、「トランザクション エラー処理」を参照してください。

このガイドの概念の詳細については、次のリソースを参照してください。

このガイドで使用されているメソッドの詳細については、次の .NET API ドキュメントを参照してください。