Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs Menu
Docs Home
/ /
/ / /

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

このガイドでは、F Core プロバイダー アプリケーションでトランザクションを使用する方法を学習できます。トランザクションは一連の書込み (write) 操作をラップします。トランザクション内のいずれかの操作が失敗した場合、プロバイダーはトランザクション内のすべての変更をロールバックします。この動作は、データの一貫性を確保するのに役立ちます。

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

  • 暗黙的なトランザクション: プロバイダーはトランザクション内の メソッドと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; }
}

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

トランザクションを使用する前に、次の要件と制限に注意してください。

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

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

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

次の例では、1 回の 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() を呼び出してトランザクションを完了します。

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

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() メソッドを呼び出します。

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

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

プロパティ
タイプ
説明

ReadConcern

ReadConcern

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

ReadPreference

ReadPreference

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

WriteConcern

WriteConcern

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

MaxCommitTime

TimeSpan?

単一の 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 を実行する必要がある場合、 エラーが返される可能性があります。このような場合、F Core プロバイダーはトランザクションを自動的に再試行しません。一時的なトランザクションエラーと再試行戦略の詳細については、「 トランザクションエラーの処理 」を参照してください。

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

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

戻る

Write Data

項目一覧