Overview
このガイドでは、 Java Reactive Streams ドライバーを使用してトランザクションを実行する方法を学習できます。 トランザクション を使用すると、すべてのデータ変更が成功するまで適用されない一連の操作を実行できます。 トランザクション内のいずれかの操作が失敗した場合、ドライバーはトランザクションをキャンセルし、表示されることなくすべてのデータ変更を破棄します。
MongoDBでは、トランザクションは論理セッション内で実行されます。 セッションは 、順番に実行されるよう関連付けられた読み取り操作または書き込み操作のグループです。 セッションを使用すると、一連の操作に対して因果整合性を有効にし、 ACID transactionを実行できます。 MongoDBは、トランザクション操作で予期せぬエラーが発生した場合でも、その操作に関わるデータの一貫性が保たれることを保証します。
Java Reactive Streams ドライバーを使用すると、 MongoClientインスタンスからClientSession型の新しいセッションを作成できます。 毎回新しいクライアントをインスタンス化するのではなく、クライアントを複数のセッションやトランザクションで再利用することを推奨します。
警告
ClientSession は、それを作成した MongoClient(または関連付けられたMongoDatabase または MongoCollection)でのみ使用します。ClientSession と、異なる MongoClient を使用すると、操作エラーが発生します。
サンプル データ
このガイドの例では、sample_restaurants.restaurants sample_mflix.moviesAtlasサンプルデータセット の コレクションと コレクションを使用します。MongoDB Atlasクラスターを無料で作成して、サンプルデータセットをロードする方法については、はじめに を参照してください。
重要
プロジェクトリ アクター ライブラリ
このガイドでは、プロジェクト Reactive ライブラリを使用して、 Java Reactive Streams ドライバー メソッドによって返された Publisher インスタンスを消費します。Project Reactive ライブラリとその使用方法の詳細については、React ドキュメントの使用開始を参照してください。このガイドでは Project React ライブラリ メソッドをどのように使用しているかについて詳しくは、 「 MongoDBへのデータの書込み 」ガイドを参照してください。
因果整合性
MongoDB は特定のクライアントセッションで因果整合性を有効にします。因果整合性モデルは、分散システム内でセッション内の操作が因果順序で実行されることを保証します。クライアントは、因果関係、または操作間の依存関係と整合性のある結果を観察します。例、ある操作が別の操作の結果に論理的に依存する一連の操作を実行すると、後続のすべての読み取りは 依存関係を反映します。
因果整合性を保証するには、クライアントセッションが次の要件を満たす必要があります。
セッションを開始するとき、ドライバーは 因果整合性 オプションを有効にする必要があります。このオプションはデフォルトで有効になっています。
操作は 1 つのスレッド上の 1 つのセッションで実行する必要があります。それ以外の場合、セッションまたはスレッドは optime とクラスター時間の値を相互に通信する必要があります。 これらの値を通信する 2 つのセッションの例については、 MongoDB Serverマニュアルの 因果整合性の例 を参照してください。
MAJORITYの読み取り保証 (read concern)を使用する必要があります。MAJORITYの書込み保証 (write concern)を使用する必要があります。これは、デフォルトの書込み保証 (write concern)の値です。
次の表では、因果整合性のあるセッションが提供する保証について説明しています。
保証 | 説明 |
|---|---|
書込み操作の結果を読み取る | 読み取り操作は、前の書込み操作の結果を反映します。 |
単調な読み取り | 読み取り操作では、前の 読み取り操作よりも前のデータ状態を反映した結果は返されません。 |
単調書込み | 書込み操作が他の書込み操作に優先する必要がある場合、サーバーはこの書込み操作を最初に実行します。 例、 |
書込み操作の前に読み取り操作をする | 書込み操作が他の読み取り操作の後に続く必要がある場合、サーバーは最初に読み取り操作を実行します。 例、 |
Tip
このセクションで述べられた概念の詳細については、次のMongoDB Serverマニュアル エントリを参照してください。
トランザクション メソッド
MongoClientインスタンスでstartSession()メソッドを使用してClientSessionを作成します。 次に、 ClientSessionが提供するメソッドを使用して、セッション状態を変更できます。 次の表は、トランザクションを管理するために使用できる方法の詳細を示しています。
方式 | 説明 |
|---|---|
| このセッションで、指定されたオプションで構成された新しいトランザクションを開始します。 セッションでトランザクションがすでに進行中の場合は、例外がスローされます。 このメソッドの詳細については、 MongoDB Serverマニュアルの startTransaction() ページを参照してください。 |
| このセッションのアクティブなトランザクションを終了します。 セッションにアクティブなトランザクションがない場合、またはトランザクションがすでにコミットされているか、または終了されている場合は、例外がスローされます。 このメソッドの詳細については、 MongoDB Serverマニュアルの abortTransaction() ページ を参照してください。 |
| このセッションのアクティブなトランザクションをコミットします。 セッションにアクティブなトランザクションがない場合、またはトランザクションが終了した場合は例外をスローします。 このメソッドの詳細については、 MongoDB Serverマニュアルの commitTransaction() ページ を参照してください。 |
トランザクションの例
次の例は、セッションを作成し、トランザクションを作成し、1 つのトランザクションで複数のコレクションにドキュメントを挿入する方法を示しています。 このコードでは、次の手順が実行されます。
startSession()メソッドを使用してクライアントからセッションを作成しますstartTransaction()メソッドを使用してトランザクションを開始しますコレクションと コレクションにドキュメントを挿入します
restaurantsmoviescommitTransaction()メソッドを使用してトランザクションをコミットします
MongoClient mongoClient = MongoClients.create(settings); MongoDatabase restaurantsDatabase = mongoClient.getDatabase("sample_restaurants"); MongoCollection<Document> restaurants = restaurantsDatabase.getCollection("restaurants"); MongoDatabase moviesDatabase = mongoClient.getDatabase("sample_mflix"); MongoCollection<Document> movies = moviesDatabase.getCollection("movies"); Mono.from(mongoClient.startSession()) .flatMap(session -> { // Begins the transaction session.startTransaction(); // Inserts documents in the given order return Mono.from(restaurants.insertOne(session, new Document("name", "Reactive Streams Pizza").append("cuisine", "Pizza"))) .then(Mono.from(movies.insertOne(session, new Document("title", "Java: Into the Streams").append("type", "Movie")))) // Commits the transaction .flatMap(result -> Mono.from(session.commitTransaction()) .thenReturn(result)) .onErrorResume(error -> Mono.from(session.abortTransaction()).then(Mono.error(error))) .doFinally(signalType -> session.close()); }) // Closes the client after the transaction completes .doFinally(signalType -> mongoClient.close()) // Prints the results of the transaction .subscribe( result -> System.out.println("Transaction succeeded"), error -> System.err.println("Transaction failed: " + error) );
注意
並列操作はサポートされていません
Java Reactive Streams ドライバーは、単一のトランザクション内での並列操作の実行中をサポートしていません。
MongoDB Server v8.0 以降を使用している場合は、一括書込み操作を使用して、1 つのトランザクション内で複数の名前空間に対して書込み操作を実行できます。詳細については、 一括書込み操作ガイドの クライアントの一括書込み セクション を参照してください。
詳細情報
このガイドで言及されている概念の詳細については、サーバー マニュアルの次のページを参照してください。
API ドキュメント
このガイドで説明した型やメソッドの詳細については、次の API ドキュメントを参照してください。