Overview
このガイドでは、MongoDB .NET/C# ドライバーを使用してトランザクションを実行する方法を学習できます。 トランザクションを使用すると、トランザクションがコミットされるまでデータを変更しない一連の操作を実行できます。 トランザクション内のいずれかの操作でエラーが返された場合、ドライバーはトランザクションをキャンセルし、変更が反映される前にすべてのデータ変更を破棄します。
MongoDBは、トランザクション操作で予期せぬエラーが発生した場合でも、その操作に関わるデータの一貫性が保たれることを保証します。
セッション
MongoDBでは、トランザクションは論理セッション内で実行されます。セッションは、順番に実行されるよう関連付けられた読み取り操作または書き込み操作のグループです。セッションにより、一連の操作に対する 因果整合性 が有効になる、またはACID transaction 内で操作を実行できるようになります。
.NET/C# ドライバーを使用すると、 MongoClientインスタンスからIClientSession型の新しいセッションを作成できます。 毎回新しいクライアントをインスタンス化するのではなく、クライアントを複数のセッションやトランザクションで再利用することを推奨します。
次の例では、StartSession() メソッドを呼び出してセッションを作成する方法を示しています。
var client = new MongoClient("mongodb://localhost:27017"); var session = client.StartSession();
警告
IClientSessionは、それを作成したMongoClient (または関連付けられたMongoDatabaseまたはMongoCollection )でのみ使用します。 IClientSessionと別のMongoClientを使用すると、操作エラーが発生します。
ClientSessionOptions
セッションの動作をカスタマイズするには、ClientSessionOptionsクラスのインスタンスを StartSession() メソッドに渡します。次の表では、ClientSessionOptionsオブジェクトに設定できるプロパティを説明します。
プロパティ | 説明 |
|---|---|
| セッションが因果的に整合しているかどうかを指定します。因果的に整合したセッションでは、ドライバーは発行された順序で操作を実行します。詳細については、「 因果整合性 |
| セッションのデフォルトのトランザクション オプションを指定します。これには、最大コミット時間、読み取り保証 (read concern)、読み込み設定 (read preference)、書込み保証 (write |
| ドライバーがスナップショット読み取りを実行するかどうかを指定します。スナップショット読み取りの詳細については、 MongoDB Serverマニュアルの「 読み取り保証(read concern)の「スナップショット」 |
| ドライバーがセッション内のすべてのデータを読み取るクラスター時間を指定します。このプロパティを設定するときは、 |
DefaultTransactionOptionsプロパティはTransactionOptionsクラスのインスタンスを受け入れます。次の表では、TransactionOptionsオブジェクトに設定できるプロパティを説明します。
プロパティ | 説明 |
|---|---|
| |
| セッション内の各トランザクションの読み取り保証 (read concern)。詳細については、 MongoDB Serverマニュアルの「 読み取り保証 」を参照してください。このプロパティを省略すると、トランザクションはセッションレベルの読み取り保証 |
| セッション内の各トランザクションの 読み込み設定(read preference)。詳細については、 MongoDB Serverマニュアルの「 読み込み設定 」を参照してください。このプロパティを省略すると、トランザクションはセッションレベルの読み込み設定 |
| セッション内の各トランザクションの書込み保証 (write concern)。詳細については、 MongoDB Serverマニュアルの「 書込み保証 |
次のコード例は、カスタム オプションを使用してセッションを作成する方法を示しています。
var client = new MongoClient("mongodb://localhost:27017"); var sessionOptions = new ClientSessionOptions { CausalConsistency = true, DefaultTransactionOptions = new TransactionOptions( readConcern: ReadConcern.Available, writeConcern: WriteConcern.Acknowledged) }; var session = client.StartSession(sessionOptions);
因果整合性
MongoDB は特定のクライアントセッションで因果整合性を有効にします。因果整合性モデルは、分散システム内でセッション内の操作が因果順序で実行されることを保証します。クライアントは、因果関係、または操作間の依存関係と整合性のある結果を観察します。例、ある操作が別の操作の結果に論理的に依存する一連の操作を実行すると、後続のすべての読み取りは 依存関係を反映します。
因果整合性を保証するには、クライアントセッションが次の要件を満たす必要があります。
セッションを開始するとき、ドライバーは 因果整合性 オプションを有効にする必要があります。このオプションはデフォルトで有効になっています。
操作は 1 つのスレッド上の 1 つのセッションで実行する必要があります。それ以外の場合、セッションまたはスレッドは optime とクラスター時間の値を相互に通信する必要があります。 これらの値を通信する 2 つのセッションの例については、 MongoDB Serverマニュアルの 因果整合性の例 を参照してください。
ReadConcern.Majorityの読み取り保証 (read concern)を使用する必要があります。WriteConcern.WMajorityの書込み保証 (write concern)を使用する必要があります。これは、デフォルトの書込み保証 (write concern)の値です。
次の表では、因果整合性のあるセッションが提供する保証について説明しています。
保証 | 説明 |
|---|---|
書込み操作の結果を読み取る | 読み取り操作は、前の書込み操作の結果を反映します。 |
単調な読み取り | 読み取り操作では、前の 読み取り操作よりも前のデータ状態を反映した結果は返されません。 |
単調書込み | 書込み操作が他の書込み操作に優先する必要がある場合、サーバーはこの書込み操作を最初に実行します。 例、 |
書込み操作の前に読み取り操作をする | 書込み操作が他の読み取り操作の後に続く必要がある場合、サーバーは最初に読み取り操作を実行します。 例、 |
Tip
このセクションで述べられた概念の詳細については、次のMongoDB Serverマニュアル エントリを参照してください。
メソッド
IClientSessionインスタンスで同期StartSession() メソッドまたは非同期StartSessionAsync() メソッドのいずれかを使用してMongoClient を作成します。次に、 IClientSessionインターフェースが提供するメソッドセットを使用してセッション状態を変更します。 トランザクションを管理する方法については、次の Synchronous Methodsタブと タブから選択してください。Asynchronous Methods
方式 | 説明 |
|---|---|
| このセッションで、指定されたオプションで構成された新しいトランザクションを開始します。セッションでトランザクションがすでに進行中の場合は、例外がスローされます。このメソッドの詳細については、サーバー マニュアルの startTransaction() |
| このセッションのアクティブなトランザクションを終了します。セッションにアクティブなトランザクションがない場合、またはトランザクションがコミットされたか、または終了した場合は、例外がスローされます。このメソッドの詳細については、サーバー マニュアルの abortTransaction() ページ |
| このセッションのアクティブなトランザクションをコミットします。セッションにアクティブなトランザクションがない場合、またはトランザクションが終了した場合は例外をスローします。このメソッドの詳細については、サーバー マニュアルの commitTransaction() ページ |
| このセッションでトランザクションを開始し、指定されたコールバックを実行します。 このメソッドの詳細については、サーバー マニュアルのwithTransaction() ページを参照してください。 重要:
|
方式 | 説明 |
|---|---|
| このセッションで、指定されたオプションで構成された新しいトランザクションを開始します。セッションでトランザクションがすでに進行中の場合は、例外がスローされます。このメソッドの詳細については、サーバー マニュアルの startTransaction() |
| このセッションのアクティブなトランザクションを終了します。セッションにアクティブなトランザクションがない場合、またはトランザクションがコミットされたか、または終了した場合は、例外がスローされます。このメソッドの詳細については、サーバー マニュアルの abortTransaction() ページ |
| このセッションのアクティブなトランザクションをコミットします。セッションにアクティブなトランザクションがない場合、またはトランザクションが終了した場合は例外をスローします。このメソッドの詳細については、サーバー マニュアルの commitTransaction() ページ |
| このセッションでトランザクションを開始し、指定されたコールバックを実行します。 このメソッドの詳細については、サーバー マニュアルのwithTransaction() ページを参照してください。 重要:
|
Tip
トランザクションを構成する
TransactionOptionsクラスのインスタンスを StartTransaction() メソッドまたは WithTransaction() メソッドに渡すことで、個々のトランザクションの動作をカスタマイズできます。ここで設定したオプションは、ClientSessionOptionsオブジェクトに設定したデフォルトのトランザクション オプションを上書きします。
例
この例では、次の手順でセッションを作成し、トランザクションを作成し、トランザクション内の複数のコレクションにドキュメントを挿入する方法を示しています。
StartSession()メソッドを使用してクライアントからセッションを作成します。トランザクションを構成するには、
TransactionOptionsオブジェクトを作成します。トランザクションを開始するには、
StartTransaction()メソッドを使用します。booksfilmsコレクションと コレクションにドキュメントを挿入します。CommitTransaction()メソッドを使用してトランザクションをコミットします。
var books = database.GetCollection<Book>("books"); var films = database.GetCollection<Film>("films"); // Begins transaction using (var session = mongoClient.StartSession()) { // Configures transaction options var transactionOptions = new TransactionOptions( readConcern: ReadConcern.Majority, writeConcern: WriteConcern.WMajority ); session.StartTransaction(transactionOptions); try { // Creates sample data var book = new Book { Title = "Beloved", Author = "Toni Morrison", InStock = true }; var film = new Film { Title = "Star Wars", Director = "George Lucas", InStock = true }; // Inserts sample data books.InsertOne(session, book); films.InsertOne(session, film); // Commits our transaction session.CommitTransaction(); } catch (Exception e) { Console.WriteLine("Error writing to MongoDB: " + e.Message); return; } // Prints a success message if no error thrown Console.WriteLine("Successfully committed transaction!"); }
Successfully committed transaction!
注意
並列操作はサポートされていません
.NET/ C#ドライバーは、単一のトランザクション内での並列操作の実行中をサポートしていません。
MongoDB Server v8.0 以降を使用している場合は、BulkWrite() メソッドまたは BulkWriteAsync() メソッドを使用して、1 つのトランザクション内で複数の名前空間に対して書込み操作を実行できます。 詳細については、「 一括書込み (write) 操作 」を参照してください。詳細情報
このガイドで言及されている概念の詳細については、サーバー マニュアルの次のページを参照してください。
API ドキュメント
このガイドで説明した型やメソッドの詳細については、次の API ドキュメントを参照してください。