AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
MongoDB Branding Shape
Click here >
Docs Menu

トランザクション

このガイドでは、 MongoDB C++ドライバーを使用して トランザクション を実行する方法を学習できます。トランザクション を使用すると、トランザクションがコミットされるまでデータを変更しない一連の操作を実行できます。 トランザクション内のいずれかの操作でエラーが返された場合、ドライバーはトランザクションをキャンセルし、変更が反映される前にすべてのデータ変更を破棄します。

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

C++ドライバーを使用すると、 mongocxx::clientインスタンスから新しいセッションを作成できます。 その後、結果の mongocxx::client_sessionインスタンスを使用してトランザクションを実行できます。 毎回新しいクライアントをインスタンス化するのではなく、クライアントを複数のセッションやトランザクションで再利用することを推奨します。

警告

mongocxx::client_session は、それを作成した mongocxx::client でのみ使用します。 client_session と別の client を使用すると、操作エラーが発生します。

重要

mongocxx::client のインスタンスはスレッドセーフではありません。 各 mongoxcc::clientインスタンスとその子インスタンス(mongocxx::client_session を含む)は、一度に 1 つのスレッドで使用する必要があります。 詳しくは、「 スレッドとフォークの安全性ガイド 」を参照してください。

MongoDB C++ドライバーは、トランザクション ライフを管理するための Callback APIと Core API を提供します。 トランザクションを開始する前に、start_session() メソッドを呼び出して mongocxx::client_session をインスタンス化する必要があります。 その後、次のいずれかの API を使用してトランザクションを実行できます。

  • Callback API : トランザクションのライフサイクルを管理し、エラー処理ロジックを自動的に組み込む高レベルのAPI 。

  • Core API : トランザクションのライフサイクルを管理し、カスタムエラー処理ロジックを実装できる低レベルのAPI 。

Tip

エラー処理の詳細については、 MongoDB Serverマニュアルの「 トランザクション エラー処理 」セクションを参照してください。

Callback API を使用して、 MongoDB C++ドライバーがトランザクションのライフサイクルを管理できるようにします。 このAPI を実装するには、mongocxx::client_sessionwith_transaction() メソッドを呼び出し、実行する操作のシーケンスを指定するコールバック関数で渡します。 with_transaction() メソッドはトランザクションを開始し、コールバック関数を実行し、エラーが発生した場合はトランザクションをコミットするか、トランザクションを終了します。 トランザクションで TransientTransactionError または UnknownTransactionCommitResult エラーが発生した場合、with_transaction() メソッドはトランザクションを再実行します。

次のコードでは、コールバックAPI を使用してトランザクションを実行し、sample_mflixデータベースの movies コレクションと comments コレクションにドキュメントを挿入します。 このコードは、次のアクションを実行します。

  1. start_session() メソッドを使用してクライアントからセッションを開始します。

  2. トランザクション中に実行する操作を指定するコールバック関数を定義します。

  3. トランザクション操作の書込み保証 (write concern)を設定するために準備するオプションオブジェクトを作成します。 読み取りと書込みセマンティクスの詳細については、 MongoDB Serverマニュアルの「読み取り保証/書込み保証/読み込み設定」セクションを参照してください。

  4. コールコールバック関数とオプションオブジェクトを引数として渡して、トランザクションを管理するために with_transaction() メソッドを呼び出します。

// Establish a connection to the MongoDB deployment
mongocxx::instance instance{};
mongocxx::client client(mongocxx::uri{"<connectionString>"});
// Define database and collection variables
auto db = client["sample_mflix"];
auto movies_collection = db["movies"];
auto comments_collection = db["comments"];
// Define a callback specifying the sequence of operations to perform during the transaction
mongocxx::client_session::with_transaction_cb callback = [&](mongocxx::client_session* session) {
// Important:: You must pass the session to the operations.
movies_collection.insert_one(*session, make_document(kvp("title", "Parasite")));
comments_collection.insert_one(*session, make_document(kvp("name", "Anjali Patel"),
kvp("text", "This is my new favorite movie!")));
};
// Define an options instance to explicitly set the write concern for the transaction operations
mongocxx::options::transaction opts;
mongocxx::write_concern wc;
wc.acknowledge_level(mongocxx::write_concern::level::k_majority);
opts.write_concern(wc);
// Start a client session
auto session = client.start_session();
try {
// Start a transaction, execute the operations in the callback function, and commit the results
session.with_transaction(callback, opts);
} catch (const mongocxx::exception& e) {
std::cout << "An exception occurred: " << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;

Core API を使用して、トランザクションのライフサイクルを管理します。 このAPI を実装するには、トランザクションを開始し、アクティブなトランザクションをコミットし、エラーが発生した場合はトランザクションを終了するために、mongocxx::client_session インターフェースのメソッドを明示的に呼び出す必要があります。 Core API にはエラー処理ロジックが自動的に組み込まれておらず、代わりに TransientTransactionErrorUnknownTransactionCommitResult などのエラーのカスタム処理ロジックを実装できます。

次の表では、mongocxx::client_session インターフェースが提供する Core APIメソッドについて説明しています。

方式
説明

start_transaction()

mongocxx::options::transaction現在のクライアントセッションで新しいトランザクションを開始します。オプションを設定するための引数として任意の インスタンスを受け入れます。オプションの完全なリストについては、 APIドキュメントの「 mongocx::options::transaction

TransientTransactionError」を参照してください。オプションが誤って設定されている場合、ネットワークやその他の一時的な障害が発生した場合、またはトランザクションがすでに進行中のセッションなどのその他のエラーが発生した場合は、例外が発生します。

ラベルの付いたエラーが返された場合は、トランザクションを終了し、成功する可能性を期待して再試行できます。このメソッドの詳細については、 MongoDB Serverマニュアルの startTransaction()ガイドを参照してください。

commit_transaction()



現在のクライアントセッションでアクティブなトランザクションをコミットします。オプションの設定に誤りがある場合、ネットワークやその他の一時的な障害が発生した場合、またはトランザクションが進行していないセッションなどのその他のエラーが発生した場合は、例外が発生します。UnknownTransactionCommitResult ラベルの付いたエラーが返された場合は、トランザクションを終了し、コミットされたトランザクションが設定された書込み保証

(write concern)を満たしたときに成功する可能性のあるものとして再試行できます。このメソッドの詳細については、 MongoDB Serverマニュアルの commitTransaction()ガイドを参照してください。

abort_transaction()

現在のクライアントセッションでアクティブなトランザクションを終了します。オプションが誤って設定されている場合、またはトランザクションが進行していないセッションなどのその他のエラーが発生した場合は、例外が発生します。このメソッドの詳細については、



MongoDB Serverマニュアルの abortTransaction()ガイドを参照してください。

Tip

mongocxx::client_sessionクラスには、セッション プロパティを検索および変更するメソッドも用意されています。詳細については、 APIドキュメントのmongocxx::client_sessionを参照してください。

次のコードでは Core API を使用してトランザクションを実行し、sample_mflixデータベースの movies コレクションと comments コレクションにドキュメントを挿入します。 このコードは、次のアクションを実行します。

  1. start_session() メソッドを使用してクライアントからセッションを開始します。

  2. トランザクション操作の書込み保証 (write concern)を設定するために準備するオプションオブジェクトを作成します。 読み取りと書込みセマンティクスの詳細については、 MongoDB Serverマニュアルの「読み取り保証/書込み保証/読み込み設定」セクションを参照してください。

  3. オプションオブジェクトを引数として渡してトランザクションを開始するための start_transaction() メソッドを呼び出します。

  4. アクティブなセッションを各操作に渡して、sample_mflixデータベース内のコレクションにドキュメントを挿入する操作を実行します。 ある操作でエラーが発生すると、トランザクション全体が中止されます。 エラーのラベルが TransientTransactionError の場合、トランザクションは再試行されます。

  5. commit_transaction() メソッドを使用してアクティブなトランザクションをコミットします。 コミットでラベル UnknownTransactionCommitResult のエラーが発生した場合、コミットは再試行されます。

// Establish a connection to the MongoDB deployment
mongocxx::instance instance{};
mongocxx::client client(mongocxx::uri{"<connectionString>"});
// Runs the txn_func and retries if TransientTransactionError occurs
using transaction_func = std::function<void(mongocxx::client_session& session)>;
auto run_with_retry = [](transaction_func txn_func,
mongocxx::client_session& session) {
while (true) {
try {
txn_func(session); // performs transaction.
break;
} catch (const mongocxx::operation_exception& oe) {
std::cout << "Transaction aborted. Caught exception during transaction."
<< std::endl;
// If transient error, retry the whole transaction.
if (oe.has_error_label("TransientTransactionError")) {
std::cout << "TransientTransactionError, retrying transaction..."
<< std::endl;
continue;
} else {
throw oe;
}
}
}
};
// Commits the active transaction and retries commit if UnknownTransactionCommitResult occurs
auto commit_with_retry = [](mongocxx::client_session& session) {
while (true) {
try {
session.commit_transaction(); // Uses write concern set at transaction start.
std::cout << "Transaction committed."
<< std::endl;
break;
} catch (const mongocxx::operation_exception& oe) {
// Can retry commit
if (oe.has_error_label("UnknownTransactionCommitResult")) {
std::cout << "UnknownTransactionCommitResult, retrying commit..."
<< std::endl;
continue;
} else {
std::cout << "Error during commit..."
<< std::endl;
throw oe;
}
}
}
};
auto txn_func = [&](mongocxx::client_session& session) {
auto& client = session.client();
// Define database and collection variables
auto db = client["sample_mflix"];
auto movies_collection = db["movies"];
auto comments_collection = db["comments"];
// Define an options instance to explicitly set the write concern for the transaction operations
mongocxx::options::transaction opts;
mongocxx::write_concern wc;
wc.acknowledge_level(mongocxx::write_concern::level::k_majority);
opts.write_concern(wc);
session.start_transaction(opts);
// Attempt to insert documents into database collections
try {
movies_collection.insert_one(session, make_document(kvp("title", "Parasite")));
comments_collection.insert_one(session, make_document(kvp("name", "Anjali Patel"),
kvp("text", "This is my new favorite movie!")));
} catch (const mongocxx::operation_exception& oe) {
std::cout << "Caught exception during transaction, aborting."
<< std::endl;
session.abort_transaction();
throw oe;
}
commit_with_retry(session);
};
// Start a client session
auto session = client.start_session();
try {
run_with_retry(txn_func, session);
} catch (const mongocxx::operation_exception& oe) {
// Do something with error
throw oe;
}

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

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

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

このガイドで説明した型やメソッドの詳細については、次の API ドキュメントを参照してください。