Docs Menu
Docs Home
/
MongoDBマニュアル
/ / / /

Session.commitTransaction()

項目一覧

  • 定義
  • 動作
Session.commitTransaction()

操作によって行われた変更をマルチドキュメントトランザクションに保存し、トランザクションを終了します。

重要

mongosh メソッド

このページでは、mongosh メソッドについて記載しています。ただし、データベースコマンドや Node.js などの言語固有のドライバーのドキュメントには該当しません

データベースコマンドについては、commitTransaction コマンドを参照してください。

MongoDB API ドライバーについては、各言語の MongoDB ドライバー ドキュメントを参照してください。

バージョン 4.2 での変更: MongoDB 4.2 以降では、シャーディングされたクラスターとレプリカセットの両方でマルチドキュメントトランザクションが利用できます。

トランザクションをコミットする際、セッションはトランザクションの開始時に指定された書込み保証(write concern)を使用します。 詳しくはSession.startTransaction()を参照してください。

"w: 1" 書込み保証 (write concern) を使用してコミットすると、フェイルオーバー プロセス中にトランザクションがロールバックされる可能性があります。

トランザクションがコミットされると、トランザクションで行われたデータ変更はトランザクションの外部に保存、表示されます。つまり、トランザクションが他の変更をロールバックしながら、一部の変更をコミットすることはありません。

トランザクションがコミットされるまで、トランザクションで行われたデータ変更はトランザクションの外部には表示されません。

ただし、トランザクションが複数のシャードに書き込む場合、すべての外部読み取り操作が、コミットされたトランザクションの結果がシャード全体で表示されるまで待機する必要はありません。たとえば、トランザクションがコミットされ、書込み 1 がシャード A で表示されているものの、書込み 2 がシャード B にまだ表示されていない場合、読み取り保証(read concern) "local" での外部読み取りは、書き込み 2 を見ることなく書き込み 1 の結果を読み取ることができます。

コミット操作でエラーが発生した場合、MongoDB ドライバーは、 retryWritesfalseに設定されているかどうかに関係なく、コミット操作を 1 回再試行します。 詳細については、「トランザクションエラーの処理 」を参照してください。

hr データベース内の従業員のレコードに変更が加えられたときに、reporting データベース内の events コレクションを hr の変更と同期させるシナリオを考えてみましょう。つまり、これらの書込み (write) が単一のトランザクションとして実行され、両方の操作が成功するか失敗するかのいずれかになるようにする必要があります。

hr データベースの employees コレクションには次のドキュメントが含まれています:

{ "_id" : ObjectId("5af0776263426f87dd69319a"), "employee" : 3, "name" : { "title" : "Mr.", "name" : "Iba Ochs" }, "status" : "Active", "department" : "ABC" }
{ "_id" : ObjectId("5af0776263426f87dd693198"), "employee" : 1, "name" : { "title" : "Miss", "name" : "Ann Thrope" }, "status" : "Active", "department" : "ABC" }
{ "_id" : ObjectId("5af0776263426f87dd693199"), "employee" : 2, "name" : { "title" : "Mrs.", "name" : "Eppie Delta" }, "status" : "Active", "department" : "XYZ" }

reporting データベースの events コレクションには次のドキュメントが含まれています:

{ "_id" : ObjectId("5af07daa051d92f02462644a"), "employee" : 1, "status" : { "new" : "Active", "old" : null }, "department" : { "new" : "ABC", "old" : null } }
{ "_id" : ObjectId("5af07daa051d92f02462644b"), "employee" : 2, "status" : { "new" : "Active", "old" : null }, "department" : { "new" : "XYZ", "old" : null } }
{ "_id" : ObjectId("5af07daa051d92f02462644c"), "employee" : 3, "status" : { "new" : "Active", "old" : null }, "department" : { "new" : "ABC", "old" : null } }

次の例では、トランザクションを開き、employees ステータスの従業員のステータスを Inactive に更新し、対応するドキュメントを events コレクションに挿入し、2 つの操作を 1 つのトランザクションとしてコミットします。

// Runs the txnFunc and retries if TransientTransactionError encountered
function runTransactionWithRetry(txnFunc, session) {
while (true) {
try {
txnFunc(session); // performs transaction
break;
} catch (error) {
// If transient error, retry the whole transaction
if (error?.errorLabels?.includes("TransientTransactionError") ) {
print("TransientTransactionError, retrying transaction ...");
continue;
} else {
throw error;
}
}
}
}
// Retries commit if UnknownTransactionCommitResult encountered
function commitWithRetry(session) {
while (true) {
try {
session.commitTransaction(); // Uses write concern set at transaction start.
print("Transaction committed.");
break;
} catch (error) {
// Can retry commit
if (error?.errorLabels?.includes("UnknownTransactionCommitResult") ) {
print("UnknownTransactionCommitResult, retrying commit operation ...");
continue;
} else {
print("Error during commit ...");
throw error;
}
}
}
}
// Updates two collections in a transactions
function updateEmployeeInfo(session) {
employeesCollection = session.getDatabase("hr").employees;
eventsCollection = session.getDatabase("reporting").events;
session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );
try{
employeesCollection.updateOne( { employee: 3 }, { $set: { status: "Inactive" } } );
eventsCollection.insertOne( { employee: 3, status: { new: "Inactive", old: "Active" } } );
} catch (error) {
print("Caught exception during transaction, aborting.");
session.abortTransaction();
throw error;
}
commitWithRetry(session);
}
// Start a session.
session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
try{
runTransactionWithRetry(updateEmployeeInfo, session);
} catch (error) {
// Do something with error
} finally {
session.endSession();
}

Tip

以下も参照してください。

戻る

Session.abortTransaction()

項目一覧