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

トランザクション

このガイドでは、 Rubyドライバーを使用して トランザクション を実行する方法を学習できます。トランザクションを使用すると、トランザクション全体がコミットされた場合にのみ、データを変更する一連の操作を実行できます。トランザクション内のいずれかの操作が成功しない場合、ドライバーはトランザクションを停止し、変更が反映される前にすべてのデータ変更を破棄します。この特徴は アトミック性と 呼ばれます。

MongoDBでは、トランザクションは論理 セッション 内で実行されます。セッションは 、順番に実行されるよう関連付けられた読み取り操作または書き込み操作のグループです。 セッションにより、一連の操作に対する 因果整合性 が有効になり、 ACID準拠のトランザクション内で操作を実行できるようになります。これは、アトミック性、整合性、分離、 耐久性 の期待を満たすトランザクションです。MongoDBは、トランザクション操作で予期せぬエラーが発生した場合でも、その操作に関わるデータの一貫性が保たれることを保証します。

Rubyドライバーを使用している場合、クライアントで start_session メソッドを呼び出すことでセッションを開始できます。その後、セッション内でトランザクションを実行できるようになります。

警告

セッションは、セッションを作成した Mongo::Client で実行中操作でのみ使用します。異なる Mongo::Client を持つセッションを使用すると、操作エラーが発生します。

MongoDB は特定のクライアントセッションで因果整合性を有効にします。因果整合性モデルは、分散システム内でセッション内の操作が因果順序で実行されることを保証します。クライアントは、因果関係、または操作間の依存関係と整合性のある結果を観察します。例、ある操作が別の操作の結果に論理的に依存する一連の操作を実行すると、後続のすべての読み取りは 依存関係を反映します。

因果整合性を保証するには、クライアントセッションが次の要件を満たす必要があります。

  • セッションを開始するとき、ドライバーは 因果整合性 オプションを有効にする必要があります。このオプションはデフォルトで有効になっています。

  • 操作は 1 つのスレッド上の 1 つのセッションで実行する必要があります。それ以外の場合、セッションまたはスレッドは optime とクラスター時間の値を相互に通信する必要があります。 これらの値を通信する 2 つのセッションの例については、 MongoDB Serverマニュアルの 因果整合性の例 を参照してください。

  • :majority の読み取り保証 (read concern)を使用する必要があります。

  • :majority の書込み保証 (write concern)を使用する必要があります。これは、デフォルトの書込み保証 (write concern)の値です。

次の表では、因果整合性のあるセッションが提供する保証について説明しています。

保証
説明

書込み操作の結果を読み取る

読み取り操作は、前の書込み操作の結果を反映します。

単調な読み取り

読み取り操作では、前の 読み取り操作よりも前のデータ状態を反映した結果は返されません。

単調書込み

書込み操作が他の書込み操作に優先する必要がある場合、サーバーはこの書込み操作を最初に実行します。

例、insert_one() を呼び出してドキュメントを挿入し、update_one() を呼び出して挿入されたドキュメント を変更すると、サーバーは最初に挿入操作を実行します。

書込み操作の前に読み取り操作をする

書込み操作が他の読み取り操作の後に続く必要がある場合、サーバーは最初に読み取り操作を実行します。

例、find() を呼び出してドキュメントを取得し、delete_one() を呼び出して取得されたドキュメントを削除すると、サーバーは最初に検索操作を実行します。

Tip

このセクションで述べられた概念の詳細については、次のMongoDB Serverマニュアル エントリを参照してください。

start_session メソッドを呼び出してセッションを開始した後、Mongo::Sessionクラスのメソッドを使用してセッション状態を管理できます。次の表では、トランザクションを管理するために使用できる方法について説明します。

方式
説明

start_transaction

このセッションで新しいトランザクションを開始します。セッションで既にアクティブなトランザクションが実行されている場合は、トランザクションを開始できません。

パラメーターとして Hash を渡すことで、読み取り保証 (read concern)、書込み保証 (write concern)、および読み込み設定 (read preference)などのトランザクションオプションを設定できます。

commit_transaction

このセッションのアクティブなトランザクションをコミットします。このメソッドは、セッションにアクティブなトランザクションがない場合、トランザクションが以前に終了された場合、または書込み競合 (write conflict)が発生している場合はエラーを返します。

abort_transaction

このセッションのアクティブなトランザクションを終了します。 このメソッドは、セッションにアクティブなトランザクションがない場合、またはトランザクションがコミットされたか、または終了した場合は、エラーを返します。

with_transaction

提供されたブロックを呼び出す前にトランザクションを開始し、ブロックの終了時にトランザクションをコミットします。ブロック内の操作またはコミット操作のいずれかで一時的なトランザクションエラーが発生した場合、ブロックおよびコミットが再度実行されます。

この例では、 sample_mflixデータベースのコレクション内のデータを変更する run_transaction メソッドを定義しています。 このコードは、次のアクションを実行します。

  • movies コレクションと users コレクションにアクセスするための Mongo::Collection インスタンスを作成します。

  • トランザクションの読み取り保証(read concern)と書込み保証(write concern)を指定します。

  • トランザクションを開始します。

  • moviesコレクションにドキュメントを挿入し、結果を出力します。

  • usersコレクション内のドキュメントを更新し、結果を出力します。

database = client.use('sample_mflix')
movies_collection = database[:movies]
users_collection = database[:users]
def run_transaction(session, movies_collection, users_collection)
transaction_options = {
read_concern: { level: "snapshot" },
write_concern: { w: "majority" }
}
session.with_transaction(transaction_options) do
# Inserts document into the "movies" collection
insert_result = movies_collection.insert_one({ name: 'The Menu', runtime: 107 }, session: session)
puts "Insert completed: #{insert_result.inspect}"
# Updates document in the "users" collection
update_result = users_collection.update_one({ name: 'Amy Phillips'}, { "$set" => { name: 'Amy Ryan' }}, session: session)
puts "Update completed: #{update_result.inspect}"
end
end
# Starts a session
session = client.start_session
begin
# Runs the transaction
run_transaction(session, movies_collection, users_collection)
puts "Transaction committed successfully."
rescue Mongo::Error::OperationFailure => e
puts "Transaction failed and was aborted. Error: #{e.message}"
ensure
session.end_session
end

注意

並列操作はサポートされていません

Rubyドライバーは、単一のトランザクション内での並列操作の実行中をサポートしていません。

MongoDB Server v8.0 以降を使用している場合は、bulk_write メソッドを使用して、1 つのトランザクション内で複数の名前空間に対して書込み操作を実行できます。詳細については、一括書込み (write) 操作のガイドを参照してください。

このガイドで言及されている概念の詳細については、 MongoDB Serverマニュアルの次のページ を参照してください。

ACID コンプライアンスの詳細については、 MongoDBウェブサイトの「 データベース管理システムのACIDプロパティに関するガイド 」に関する記事を参照してください。

挿入操作の詳細については、ドキュメントの挿入ガイドを参照してください。

このガイドで言及されているメソッドとタイプの詳細については、次のAPIドキュメントを参照してください。