Overview
このガイドでは、 Kotlin Syncドライバーを使用してトランザクションを実行する方法を学習できます。 トランザクション を使用すると、トランザクションがコミットされるまでデータを変更しない一連の操作を実行できます。 トランザクション内のいずれかの操作でエラーが返された場合、ドライバーはトランザクションをキャンセルし、変更が反映される前にすべてのデータ変更を破棄します。
MongoDB では、トランザクションは論理セッション内で実行されます。 セッションは 、順番に実行されるよう関連付けられた読み取り操作または書き込み操作のグループです。 セッションにより、一連の操作に対する因果整合性が有効になり、 ACID 準拠のトランザクション(不可分性、整合性、分離、耐久性の期待を満たすトランザクション)内で操作を実行できるようになります。 MongoDBは、トランザクション操作で予期せぬエラーが発生した場合でも、その操作に関わるデータの一貫性が保たれることを保証します。
Kotlin Syncドライバーを使用すると、 MongoClientインスタンスからClientSessionタイプの新しいセッションを作成できます。 毎回新しいクライアントを作成するのではなく、 MongoClientを複数のセッションやトランザクションで再利用することを推奨します。
警告
ClientSession は、それを作成した MongoClient(または関連付けられたMongoDatabase または MongoCollection)でのみ使用します。ClientSession と、異なる MongoClient を使用すると、操作エラーが発生します。
因果整合性
MongoDB は特定のクライアントセッションで因果整合性を有効にします。因果整合性モデルは、分散システム内でセッション内の操作が因果順序で実行されることを保証します。クライアントは、因果関係、または操作間の依存関係と整合性のある結果を観察します。例、ある操作が別の操作の結果に論理的に依存する一連の操作を実行すると、後続のすべての読み取りは 依存関係を反映します。
因果整合性を保証するには、クライアントセッションが次の要件を満たす必要があります。
セッションを開始するとき、ドライバーは 因果整合性 オプションを有効にする必要があります。このオプションはデフォルトで有効になっています。
操作は 1 つのスレッド上の 1 つのセッションで実行する必要があります。それ以外の場合、セッションまたはスレッドは optime とクラスター時間の値を相互に通信する必要があります。 これらの値を通信する 2 つのセッションの例については、 MongoDB Serverマニュアルの 因果整合性の例 を参照してください。
ReadConcern.MAJORITYの読み取り保証 (read concern)を使用する必要があります。WriteConcern.MAJORITYの書込み保証 (write concern)を使用する必要があります。これは、デフォルトの書込み保証 (write concern)の値です。
次の表では、因果整合性のあるセッションが提供する保証について説明しています。
保証 | 説明 |
|---|---|
書込み操作の結果を読み取る | 読み取り操作は、前の書込み操作の結果を反映します。 |
単調な読み取り | 読み取り操作では、前の 読み取り操作よりも前のデータ状態を反映した結果は返されません。 |
単調書込み | 書込み操作が他の書込み操作に優先する必要がある場合、サーバーはこの書込み操作を最初に実行します。 例、 |
書込み操作の前に読み取り操作をする | 書込み操作が他の読み取り操作の後に続く必要がある場合、サーバーは最初に読み取り操作を実行します。 例、 |
Tip
このセクションで述べられた概念の詳細については、次のMongoDB Serverマニュアル エントリを参照してください。
サンプル データ
このガイドの例では、Atlas サンプル データセットの sample_restaurants.restaurants コレクションを使用します。無料の MongoDB 配置を作成し、サンプルデータセットを読み込む方法については、MongoDB の スタートガイドを参照してください。
このコレクション内のドキュメントは、次の Kotlin データ クラスによってモデル化されます。
data class Restaurant(val name: String, val cuisine: String)
メソッド
MongoClientインスタンスでstartSession()メソッドを使用してClientSessionを作成します。 次に、 ClientSessionが提供するメソッドを使用して、セッション状態を変更できます。 次の表では、トランザクションを管理するために使用できる方法について説明します。
方式 | 説明 |
|---|---|
| このセッションで、指定されたオプションで構成された新しいトランザクションを開始します。セッションで既にトランザクションが実行中の場合はエラーを返します。このメソッドの詳細については、サーバー マニュアルの「startTransaction() ページ」を参照してください。 |
| このセッションのアクティブなトランザクションを終了します。セッションにアクティブなトランザクションがない場合、またはトランザクションがコミットされたか、または終了した場合は、エラーを返します。このメソッドの詳細については、サーバー マニュアルの abortTransaction() ページ を参照してください。 |
| このセッションのアクティブなトランザクションをコミットします。セッションにアクティブなトランザクションがない場合、またはトランザクションが終了した場合はエラーを返します。このメソッドの詳細については、サーバー マニュアルの commitTransaction() ページを参照してください。 |
| このセッションでトランザクションを開始し、指定された関数をトランザクション内で実行する。 |
例
次の例は、セッションを作成し、トランザクションを作成し、次の手順で 1 つのトランザクション内でコレクションにドキュメントを挿入する方法を示しています。
startSession()メソッドを使用してクライアントからセッションを作成します。複数のドキュメントを
restaurantsコレクションに挿入するには、insertRestaurantsInTransaction()メソッドを定義します。トランザクションを開始するには、
withTransaction()メソッドを使用します。withTransaction()メソッドは挿入操作を実行し、トランザクションをコミットします。 いずれかの操作でエラーが発生した場合、withTransaction()はトランザクションをキャンセルします。MongoClient.close()メソッドを使用してサーバーへの接続を閉じます。
// Creates a new MongoClient to manage your connection val client = MongoClient.create("<connection string>") // Gets the database and collection val database = client.getDatabase("sample_restaurants") val collection = database.getCollection<Restaurant>("restaurants") // Inserts restaurants into the collection fun insertRestaurantsInTransaction(session: ClientSession) { // Inserts restaurants within the transaction collection.insertOne( session, Restaurant("Kotlin Sync Pizza", "Pizza") ) collection.insertOne( session, Restaurant("Kotlin Sync Burger", "Burger") ) } // Starts a client session client.startSession().use { session -> try { // Sets transaction options val txnOptions = TransactionOptions.builder() .readConcern(ReadConcern.LOCAL) .writeConcern(WriteConcern.MAJORITY) .build() // Uses the withTransaction method to start a transaction and run the given function session.withTransaction({ insertRestaurantsInTransaction(session) println("Transaction succeeded") }, txnOptions) } catch (e: Exception) { println("Transaction failed: ${e.message}") } } // Closes the MongoClient client.close()
トランザクションをさらに制御する必要がある場合は、 startTransaction()メソッドを使用できます。 このメソッドを前のセクションで説明した メソッドとcommitTransaction() abortTransaction()メソッドと組み合わせて使用すると、トランザクションのライフサイクルを手動で管理できます。
注意
並列操作はサポートされていません
Kotlin Syncドライバーは、単一のトランザクション内での並列操作の実行中をサポートしていません。
MongoDB Server v8.0 以降を使用している場合は、一括書込み操作を使用して、1 つのトランザクション内で複数の名前空間に対して書込み操作を実行できます。詳細については、 一括書込み操作ガイドの クライアントの一括書込み セクション を参照してください。
詳細情報
このガイドで言及されている概念の詳細については、サーバー マニュアルの次のページを参照してください。
ACID compliance の詳細については、 「 データベース管理システムの ACID プロパティとは 」を参照してください。 MongoDB Webサイトの記事。
API ドキュメント
このガイドで説明した型やメソッドの詳細については、次の API ドキュメントを参照してください。