定義
Session.abortTransaction()マルチドキュメントトランザクションを終了し、トランザクション内の操作によって行われたデータ変更をロールバックします。 つまり、トランザクション内の操作によって行われた変更を保存せずにトランザクションは終了します。
マルチドキュメントトランザクションは、シャーディングされたクラスターとレプリカセットの両方で使用できます。
Session.abortTransaction()は、値を返しません。重要
mongosh メソッド
This page documents a
mongoshmethod. This is not the documentation for database commands or language-specific drivers, such as Node.js.データベースコマンドについては、
abortTransactionコマンドを参照してください。MongoDB API ドライバーについては、各言語の「MongoDB ドライバーのドキュメント」を参照してください。
互換性
このメソッドは、次の環境でホストされている配置で使用できます。
- MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud
注意
This command is supported in all MongoDB Atlas clusters. For information on Atlas support for all commands, see Unsupported Commands.
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
動作
アトミック性
トランザクションが中止されると、トランザクション内の書込み (write) によって行われたすべてのデータ変更は、参照可能にならずに破棄され、トランザクションは終了します。
セキュリティ
監査付きで実行している場合、中止されたトランザクションの操作は引き続き監査されます。
再試行可能
中止操作でエラーが発生した場合、MongoDB ドライバーは、 retryWritesがtrueに設定されているかどうかに関係なく、中止操作を 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" }
employeesコレクションでは、 employeeフィールドに一意のインデックスがあります。
db.employees.createIndex( { employee: 1 }, { unique: true } )
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 } }
次の例では、トランザクションを開き、 eventsコレクションにレコードを追加し、 employeesコレクションにドキュメントを追加しようとします。 操作で操作またはトランザクションのコミットのいずれかでエラーが発生した場合、セッションはトランザクションを中止します。
// 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; } } } } // Performs inserts and count in a transaction function updateEmployeeInfo(session) { employeesCollection = session.getDatabase("hr").employees; eventsCollection = session.getDatabase("reporting").events; // Start a transaction for the session that uses: // - read concern "snapshot" // - write concern "majority" session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } ); try{ eventsCollection.insertOne( { employee: 3, status: { new: "Active", old: null }, department: { new: "XYZ", old: null } } ); // Count number of events for employee 3 var countDoc = eventsCollection.aggregate( [ { $match: { employee: 3 } }, { $count: "eventCounts" } ] ).next(); print( "events count (in active transaction): " + countDoc.eventCounts ); // The following operations should fail as an employee ``3`` already exist in employees collection employeesCollection.insertOne( { employee: 3, name: { title: "Miss", name: "Terri Bachs" }, status: "Active", department: "XYZ" } ); } catch (error) { print("Caught exception during transaction, aborting."); session.abortTransaction(); throw error; } commitWithRetry(session); } // End of updateEmployeeInfo function // Start a session. session = db.getMongo().startSession( { readPreference: { mode: "primary" } } ); try{ runTransactionWithRetry(updateEmployeeInfo, session); } catch (error) { // Do something with error } finally { session.endSession(); }