From 25b5bb8d230004469425922722a279d131936162 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Fri, 8 Nov 2024 13:49:11 -0500 Subject: [PATCH 01/32] (DOCSP-45012) Added file. --- source/index.txt | 1 + source/transactions.txt | 177 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 source/transactions.txt diff --git a/source/index.txt b/source/index.txt index 39f8a176..611d3fe5 100644 --- a/source/index.txt +++ b/source/index.txt @@ -16,6 +16,7 @@ MongoDB C++ Driver Write Data Indexes Aggregation + Transactions Security Specialized Data Formats C++17 Polyfill diff --git a/source/transactions.txt b/source/transactions.txt new file mode 100644 index 00000000..b23cfd81 --- /dev/null +++ b/source/transactions.txt @@ -0,0 +1,177 @@ +.. _cpp-transactions: + +============ +Transactions +============ + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example, rollback, undo operation + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +In this guide, you can learn how to use the {+driver-long+} to perform +**transactions**. :manual:`Transactions ` allow +you to run a series of operations that do not change any data until the +transaction is committed. If any operation in the transaction returns an +error, the driver cancels the transaction and discards all data changes +before they ever become visible. + +In MongoDB, transactions run within logical **sessions**. A +:manual:`session ` is a grouping of related +read or write operations that you intend to run sequentially. Sessions +enable :manual:`causal consistency +` for a +group of operations or allow you to execute operations in an +:website:`ACID transaction `. MongoDB +guarantees that the data involved in your transaction operations remains +consistent, even if the operations encounter unexpected errors. + +When using the {+driver-short+}, you can create a new session from a +``Client`` instance as a ``Session`` type. We recommend that you reuse +your client for multiple sessions and transactions instead of +instantiating a new client each time. + +.. warning:: + + Use a ``Session`` only with the ``Client`` (or associated + ``Database`` or ``Collection``) that created it. Using a + ``Session`` with a different ``Client`` results in operation + errors. + +.. warning:: + + Implementations of ``Session`` are not safe for concurrent use by multiple `goroutines + `__. + +Methods +------- + +After you start a session by using the ``StartSession()`` method, you can modify +the session state by using the method set provided by the ``Session`` interface. The +following table describes these methods: + +.. list-table:: + :widths: 25 75 + :header-rows: 1 + + * - Method + - Description + + * - ``StartTransaction()`` + - | Starts a new transaction, configured with the given options, on + this session. Returns an error if there is already + a transaction in progress for the session. To learn more about + this method, see the :manual:`startTransaction() page + ` in the Server manual. + | + | **Parameter**: ``TransactionOptions`` + | **Return Type**: ``error`` + + * - ``AbortTransaction()`` + - | Ends the active transaction for this session. Returns an + error if there is no active transaction for the session or the + transaction has been committed or ended. To learn more about + this method, see the :manual:`abortTransaction() page + ` in the Server manual. + | + | **Parameter**: ``Context`` + | **Return Type**: ``error`` + + * - ``CommitTransaction()`` + - | Commits the active transaction for this session. Returns an + error if there is no active transaction for the session or if the + transaction was ended. To learn more about + this method, see the :manual:`commitTransaction() page + ` in the Server manual. + | + | The ``CommitTransaction()`` method is an idempotent function, which + means that you can attempt to commit a transaction multiple times without changing data after the first successful commit. + A transaction can succeed but return an error with the + ``UnknownTransactionCommitResult`` label. If you rerun the + ``CommitTransaction()`` method after receiving this error, + your data is not changed by the repeat attempts. + + | + | **Parameter**: ``Context`` + | **Return Type**: ``error`` + + * - ``WithTransaction()`` + - | Starts a transaction on this session and runs the ``fn`` + callback. + | + | **Parameters**: ``Context``, ``fn func(ctx SessionContext)``, ``TransactionOptions`` + | **Return Type**: ``interface{}``, ``error`` + + * - ``EndSession()`` + - | Ends any existing transactions and closes the session. + | + | **Parameter**: ``Context`` + | **Return Type**: none + +The ``Session`` interface also has methods to retrieve session +properties and modify mutable session properties. Find more information +in the :ref:`API documentation `. + +Example +------- + +The following example shows how you can create a session, create a +transaction, and commit a multi-document insert operation through the +following steps: + +1. Create a session from the client using the ``StartSession()`` method. +#. Use the ``WithTransaction()`` method to start a transaction. +#. Insert multiple documents. The ``WithTransaction()`` method executes the + insert and commits the transaction. If any operation results in + errors, ``WithTransaction()`` handles canceling the transaction. +#. Close the transaction and session using the ``EndSession()`` method. + +.. literalinclude:: /includes/fundamentals/code-snippets/transaction.go + :language: go + :dedent: + :emphasize-lines: 5,10,14-15 + :start-after: start-session + :end-before: end-session + +If you require more control over your transactions, you can find an example +showing how to manually create, commit, and end transactions in the +`full code example `__. + +Additional Information +---------------------- + +For more information about insert operations, see the +:ref:`golang-insert-guide` fundamentals page. + +For more information about specifying write concerns in the +{+driver-short+}, see :ref:`Write Concern `. + +For an additional example using sessions and transactions with the {+driver-short+}, see the +:website:`developer blog post on Multi-Document ACID Transactions +`. + +.. _api-docs-transaction: + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the types or methods discussed in this +guide, see the following API Documentation: + +- `Session <{+api+}/mongo#Session>`__ +- `Client <{+api+}/mongo#Client>`__ +- `StartSession() <{+api+}/mongo#Client.StartSession>`__ +- `TransactionOptions <{+api+}/mongo/options#TransactionOptions>`__ +- `SetWriteConcern() <{+api+}/mongo/options#TransactionOptions.SetWriteConcern>`__ +- `InsertMany() <{+api+}/mongo#Collection.InsertMany>`__ \ No newline at end of file From a41f2640c0f73a7a16d568e1cc3c73f65d6104dc Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Mon, 11 Nov 2024 12:10:45 -0500 Subject: [PATCH 02/32] (DOCSP-45012) Added methods to page. --- source/transactions.txt | 74 +++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/source/transactions.txt b/source/transactions.txt index b23cfd81..c780b0e1 100644 --- a/source/transactions.txt +++ b/source/transactions.txt @@ -38,27 +38,26 @@ guarantees that the data involved in your transaction operations remains consistent, even if the operations encounter unexpected errors. When using the {+driver-short+}, you can create a new session from a -``Client`` instance as a ``Session`` type. We recommend that you reuse +``mongocxx::client`` instance as a ``mongocxx::client_session`` type. We recommend that you reuse your client for multiple sessions and transactions instead of instantiating a new client each time. .. warning:: - Use a ``Session`` only with the ``Client`` (or associated - ``Database`` or ``Collection``) that created it. Using a - ``Session`` with a different ``Client`` results in operation + Use a ``mongocxx::client_session`` only with the ``mongocxx::client`` (or associated + ``mongocxx::database`` or ``mongocxx::collection``) that created it. Using a + ``client_session`` with a different ``client`` results in operation errors. .. warning:: - Implementations of ``Session`` are not safe for concurrent use by multiple `goroutines - `__. + Implementations of ``mongocxx::`` are not thread-safe for concurrent use by multiple threads. Methods ------- -After you start a session by using the ``StartSession()`` method, you can modify -the session state by using the method set provided by the ``Session`` interface. The +After you start a session by using the ``start_session()`` method, you can modify +the session state by using the method set provided by the ``mongocxx::client_session`` interface. The following table describes these methods: .. list-table:: @@ -68,27 +67,25 @@ following table describes these methods: * - Method - Description - * - ``StartTransaction()`` + * - ``start_transaction()`` - | Starts a new transaction, configured with the given options, on - this session. Returns an error if there is already + the current client session. Returns an error if there is already a transaction in progress for the session. To learn more about this method, see the :manual:`startTransaction() page ` in the Server manual. | - | **Parameter**: ``TransactionOptions`` - | **Return Type**: ``error`` + | **Parameter Type**: ``transaction_opts`` - * - ``AbortTransaction()`` + * - ``abort_transcaction()`` - | Ends the active transaction for this session. Returns an error if there is no active transaction for the session or the transaction has been committed or ended. To learn more about this method, see the :manual:`abortTransaction() page ` in the Server manual. | - | **Parameter**: ``Context`` - | **Return Type**: ``error`` + | **Parameter Type**: ``Context`` - * - ``CommitTransaction()`` + * - ``commit_transaction()`` - | Commits the active transaction for this session. Returns an error if there is no active transaction for the session or if the transaction was ended. To learn more about @@ -103,21 +100,18 @@ following table describes these methods: your data is not changed by the repeat attempts. | - | **Parameter**: ``Context`` - | **Return Type**: ``error`` + | **Parameter Type**: ``Context`` - * - ``WithTransaction()`` + * - ``with_transaction()`` - | Starts a transaction on this session and runs the ``fn`` callback. | - | **Parameters**: ``Context``, ``fn func(ctx SessionContext)``, ``TransactionOptions`` - | **Return Type**: ``interface{}``, ``error`` + | **Parameter Types**: ``callback``, ``transaction_opts`` - * - ``EndSession()`` - - | Ends any existing transactions and closes the session. + * - ``~client_session()`` + - | Destructor for the ``mongocxx::client_session`` class. Ends any existing transactions and closes the session. | - | **Parameter**: ``Context`` - | **Return Type**: none + | **Parameter Type**: ``Context`` The ``Session`` interface also has methods to retrieve session properties and modify mutable session properties. Find more information @@ -151,15 +145,19 @@ showing how to manually create, commit, and end transactions in the Additional Information ---------------------- -For more information about insert operations, see the -:ref:`golang-insert-guide` fundamentals page. +To learn more about the concepts discussed in this guide, see the following pages in the +Server manual: + +- :manual:`Transactions ` +- :manual:`session ` +- :manual:`causal consistency +` -For more information about specifying write concerns in the -{+driver-short+}, see :ref:`Write Concern `. +To learn more about ACID complicance, see the :website:`ACID Properties in Database Management Systems ` +guide on the MongoDB website. -For an additional example using sessions and transactions with the {+driver-short+}, see the -:website:`developer blog post on Multi-Document ACID Transactions -`. +For more information about insert operations, see the +:ref:`Insert cpp-write-insert` guide page. .. _api-docs-transaction: @@ -174,4 +172,14 @@ guide, see the following API Documentation: - `StartSession() <{+api+}/mongo#Client.StartSession>`__ - `TransactionOptions <{+api+}/mongo/options#TransactionOptions>`__ - `SetWriteConcern() <{+api+}/mongo/options#TransactionOptions.SetWriteConcern>`__ -- `InsertMany() <{+api+}/mongo#Collection.InsertMany>`__ \ No newline at end of file +- `InsertMany() <{+api+}/mongo#Collection.InsertMany>`__ + +- `mongocxx::client <{+api+}/classmongocxx_1_1client.html>`__ +- `mongocxx::client_session <{+api+}/mongocxx-3.3.2/classmongocxx_1_1client__session.html>`__ +- `start_session() <{+api+}/classmongocxx_1_1client.html#a42a89f74fb0015751a3015a677aae099>`__ +- `start_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#a84ea5613813e6efbe065e3f39e1f972b>`__ +- `abort_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#aabb8247a655741af6fe0f78bef8116e1>`__ +- `commit_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#ad2d1a8f7c77542db6ec7629d162761ff>`__ +- `with_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#a3dcdf91bf72e69bf7e63a7c8ad859b93>`__ +- `insert_one() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#af040f1fcb1ac406037bf1cbcdb300061>`__ +- `insert_many() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#a61ebaa0c63296761637ce45115512085>`__ \ No newline at end of file From 7c0b0139654a47cfaa9319baaae85da58b0e164c Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Mon, 11 Nov 2024 15:49:47 -0500 Subject: [PATCH 03/32] (DOCSP-45012) Added code. --- .../includes/usage-examples/transactions.cpp | 45 +++++++++++++++++++ source/transactions.txt | 31 +++++-------- 2 files changed, 55 insertions(+), 21 deletions(-) create mode 100644 source/includes/usage-examples/transactions.cpp diff --git a/source/includes/usage-examples/transactions.cpp b/source/includes/usage-examples/transactions.cpp new file mode 100644 index 00000000..46e5b8ba --- /dev/null +++ b/source/includes/usage-examples/transactions.cpp @@ -0,0 +1,45 @@ + +// start-session +// Create a mongocxx::instance to initialize the drive and initialize a mongocxx::client +// using your MongoDB deployment connection string to establish a connection to the MongoDB server +mongocxx::instance instance{}; +mongocxx::client client(mongocxx::uri uri("")); + +// Define the database and collection +// Connect to the movies collection in the preloaded Atlas sample_mflix database +auto db = client["sample_mflix"]; +auto collection = db["movies"]; + +// Prepare to set majority write explicitly. Note: on Atlas deployments this won't always be +// needed. The suggested Atlas connection string includes majority write concern by default. +write_concern wc_majority{}; +wc_majority.acknowledge_level(write_concern::level::k_majority); + +// Start a client session +auto session = client.start_session(); + +// Define a callback function that specifies the sequence of operations to perform inside the transaction. +client_session::with_transaction_cb callback = [&](client_session* session) { + // Important:: You must pass the session to the operations. + foo.insert_one(*session, make_document(kvp("title", "Parasite"))); + bar.insert_one(*session, make_document(kvp("title", "The Banshees of Inisherin"))); +}; + +// Call the with_transaction() method and pass in the callback function +// and an options object that sets the write concern for the transaction operations +try { + // Define an options object that sets the write concern for the transaction operations + options::transaction opts; + opts.write_concern(wc_majority); + + // Call with_transactions to run and commit the insert operations defined in the callback function + session.with_transaction(callback, opts); +} catch (const mongocxx::exception& e) { + std::cout << "An exception occurred: " << e.what() << std::endl; + return EXIT_FAILURE; +} + +// Return the status of the transaction. This automatically calls the mongocxx::client_session destructor, +// closing the connection to the server. +return EXIT_SUCCESS; +// end-session diff --git a/source/transactions.txt b/source/transactions.txt index c780b0e1..aa0cb7ac 100644 --- a/source/transactions.txt +++ b/source/transactions.txt @@ -21,19 +21,16 @@ Overview -------- In this guide, you can learn how to use the {+driver-long+} to perform -**transactions**. :manual:`Transactions ` allow +**transactions**. Transactions allow you to run a series of operations that do not change any data until the transaction is committed. If any operation in the transaction returns an error, the driver cancels the transaction and discards all data changes before they ever become visible. In MongoDB, transactions run within logical **sessions**. A -:manual:`session ` is a grouping of related -read or write operations that you intend to run sequentially. Sessions -enable :manual:`causal consistency -` for a -group of operations or allow you to execute operations in an -:website:`ACID transaction `. MongoDB +session is a grouping of related read or write operations that you intend to run sequentially. +Sessions enable causal consistency for a group of operations +or allow you to execute operations in an ACID transaction. MongoDB guarantees that the data involved in your transaction operations remains consistent, even if the operations encounter unexpected errors. @@ -51,7 +48,7 @@ instantiating a new client each time. .. warning:: - Implementations of ``mongocxx::`` are not thread-safe for concurrent use by multiple threads. + Implementations of ``mongocxx::client_session`` are not thread-safe for concurrent use by multiple threads. Methods ------- @@ -74,7 +71,7 @@ following table describes these methods: this method, see the :manual:`startTransaction() page ` in the Server manual. | - | **Parameter Type**: ``transaction_opts`` + | **Parameter Type**: ** optional ** ``mongocxx::options::transaction`` * - ``abort_transcaction()`` - | Ends the active transaction for this session. Returns an @@ -131,8 +128,8 @@ following steps: errors, ``WithTransaction()`` handles canceling the transaction. #. Close the transaction and session using the ``EndSession()`` method. -.. literalinclude:: /includes/fundamentals/code-snippets/transaction.go - :language: go +.. literalinclude:: /includes/usage-examples/transactions.cpp + :language: cpp :dedent: :emphasize-lines: 5,10,14-15 :start-after: start-session @@ -150,8 +147,7 @@ Server manual: - :manual:`Transactions ` - :manual:`session ` -- :manual:`causal consistency -` +- :manual:`causal consistency ` To learn more about ACID complicance, see the :website:`ACID Properties in Database Management Systems ` guide on the MongoDB website. @@ -167,16 +163,9 @@ API Documentation To learn more about any of the types or methods discussed in this guide, see the following API Documentation: -- `Session <{+api+}/mongo#Session>`__ -- `Client <{+api+}/mongo#Client>`__ -- `StartSession() <{+api+}/mongo#Client.StartSession>`__ -- `TransactionOptions <{+api+}/mongo/options#TransactionOptions>`__ -- `SetWriteConcern() <{+api+}/mongo/options#TransactionOptions.SetWriteConcern>`__ -- `InsertMany() <{+api+}/mongo#Collection.InsertMany>`__ - - `mongocxx::client <{+api+}/classmongocxx_1_1client.html>`__ - `mongocxx::client_session <{+api+}/mongocxx-3.3.2/classmongocxx_1_1client__session.html>`__ -- `start_session() <{+api+}/classmongocxx_1_1client.html#a42a89f74fb0015751a3015a677aae099>`__ +- `start_session() <{+api+}/classmongocxx_1_1v__noabi_1_1client.html#a03535128dbe5be973a08764b7741f24e>`__ - `start_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#a84ea5613813e6efbe065e3f39e1f972b>`__ - `abort_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#aabb8247a655741af6fe0f78bef8116e1>`__ - `commit_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#ad2d1a8f7c77542db6ec7629d162761ff>`__ From 64cdb5ca69ada941040f0d90908a3bff3598b89d Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Tue, 12 Nov 2024 10:13:06 -0500 Subject: [PATCH 04/32] (DOCSP-45012) Edits. --- source/transactions.txt | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/source/transactions.txt b/source/transactions.txt index aa0cb7ac..3e5b699e 100644 --- a/source/transactions.txt +++ b/source/transactions.txt @@ -71,7 +71,7 @@ following table describes these methods: this method, see the :manual:`startTransaction() page ` in the Server manual. | - | **Parameter Type**: ** optional ** ``mongocxx::options::transaction`` + | **Parameter Type**: **Optional**. ``mongocxx::options::transaction`` * - ``abort_transcaction()`` - | Ends the active transaction for this session. Returns an @@ -121,12 +121,16 @@ The following example shows how you can create a session, create a transaction, and commit a multi-document insert operation through the following steps: -1. Create a session from the client using the ``StartSession()`` method. -#. Use the ``WithTransaction()`` method to start a transaction. -#. Insert multiple documents. The ``WithTransaction()`` method executes the - insert and commits the transaction. If any operation results in - errors, ``WithTransaction()`` handles canceling the transaction. -#. Close the transaction and session using the ``EndSession()`` method. +1. Create a session from the client using the ``start_session()`` method. +#. Create a callback function with the series of operations you want to +run in your transaction. +# Define any options you want to add to your transaction. +# Call the ``with_transactions()`` method and pass in your callback function and +options to start a transaction. The ``with_transactions()`` method executes and +commits the transaction. If any operation results in +errors, ``with_transactions()`` handles canceling the transaction. +#. Return from your operation. This will automatically call the ``~end_session()`` +destructor to close the transaction and client session. .. literalinclude:: /includes/usage-examples/transactions.cpp :language: cpp @@ -153,7 +157,7 @@ To learn more about ACID complicance, see the :website:`ACID Properties in Datab guide on the MongoDB website. For more information about insert operations, see the -:ref:`Insert cpp-write-insert` guide page. +:ref:`Insert ` guide page. .. _api-docs-transaction: From 15288746f2b5c6e2209f1a5fcd81a32bd6c23f4d Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Tue, 12 Nov 2024 10:21:37 -0500 Subject: [PATCH 05/32] (DOCSP-45012) Fix list formatting. --- source/transactions.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/transactions.txt b/source/transactions.txt index 3e5b699e..b138152b 100644 --- a/source/transactions.txt +++ b/source/transactions.txt @@ -124,8 +124,8 @@ following steps: 1. Create a session from the client using the ``start_session()`` method. #. Create a callback function with the series of operations you want to run in your transaction. -# Define any options you want to add to your transaction. -# Call the ``with_transactions()`` method and pass in your callback function and +#. Define any options you want to add to your transaction. +#. Call the ``with_transactions()`` method and pass in your callback function and options to start a transaction. The ``with_transactions()`` method executes and commits the transaction. If any operation results in errors, ``with_transactions()`` handles canceling the transaction. From 978314477572702fa96d622455d2b60848a52929 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Tue, 12 Nov 2024 11:20:48 -0500 Subject: [PATCH 06/32] (DOCSP-45012) Fix list formatting. --- source/includes/usage-examples/transactions.cpp | 7 +++---- source/transactions.txt | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/source/includes/usage-examples/transactions.cpp b/source/includes/usage-examples/transactions.cpp index 46e5b8ba..36369844 100644 --- a/source/includes/usage-examples/transactions.cpp +++ b/source/includes/usage-examples/transactions.cpp @@ -5,8 +5,7 @@ mongocxx::instance instance{}; mongocxx::client client(mongocxx::uri uri("")); -// Define the database and collection -// Connect to the movies collection in the preloaded Atlas sample_mflix database +// Define database and collection variables auto db = client["sample_mflix"]; auto collection = db["movies"]; @@ -28,11 +27,11 @@ client_session::with_transaction_cb callback = [&](client_session* session) { // Call the with_transaction() method and pass in the callback function // and an options object that sets the write concern for the transaction operations try { - // Define an options object that sets the write concern for the transaction operations + // Define an options instance to set the write concern for the transaction operations options::transaction opts; opts.write_concern(wc_majority); - // Call with_transactions to run and commit the insert operations defined in the callback function + // Run and commit the insert operations defined in the callback function session.with_transaction(callback, opts); } catch (const mongocxx::exception& e) { std::cout << "An exception occurred: " << e.what() << std::endl; diff --git a/source/transactions.txt b/source/transactions.txt index b138152b..98627a01 100644 --- a/source/transactions.txt +++ b/source/transactions.txt @@ -135,7 +135,6 @@ destructor to close the transaction and client session. .. literalinclude:: /includes/usage-examples/transactions.cpp :language: cpp :dedent: - :emphasize-lines: 5,10,14-15 :start-after: start-session :end-before: end-session From fb50c58aa3d192b605627e3f64670859807d1065 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Mon, 18 Nov 2024 16:12:19 -0500 Subject: [PATCH 07/32] (DOCSP-45012) Added examples for manual transactions and moved transactions page under Write. --- .../includes/usage-examples/transactions.cpp | 44 ------ source/includes/write/transactions.cpp | 96 +++++++++++++ source/index.txt | 1 - source/write.txt | 1 + source/{ => write}/transactions.txt | 127 +++++++++--------- 5 files changed, 162 insertions(+), 107 deletions(-) delete mode 100644 source/includes/usage-examples/transactions.cpp create mode 100644 source/includes/write/transactions.cpp rename source/{ => write}/transactions.txt (51%) diff --git a/source/includes/usage-examples/transactions.cpp b/source/includes/usage-examples/transactions.cpp deleted file mode 100644 index 36369844..00000000 --- a/source/includes/usage-examples/transactions.cpp +++ /dev/null @@ -1,44 +0,0 @@ - -// start-session -// Create a mongocxx::instance to initialize the drive and initialize a mongocxx::client -// using your MongoDB deployment connection string to establish a connection to the MongoDB server -mongocxx::instance instance{}; -mongocxx::client client(mongocxx::uri uri("")); - -// Define database and collection variables -auto db = client["sample_mflix"]; -auto collection = db["movies"]; - -// Prepare to set majority write explicitly. Note: on Atlas deployments this won't always be -// needed. The suggested Atlas connection string includes majority write concern by default. -write_concern wc_majority{}; -wc_majority.acknowledge_level(write_concern::level::k_majority); - -// Start a client session -auto session = client.start_session(); - -// Define a callback function that specifies the sequence of operations to perform inside the transaction. -client_session::with_transaction_cb callback = [&](client_session* session) { - // Important:: You must pass the session to the operations. - foo.insert_one(*session, make_document(kvp("title", "Parasite"))); - bar.insert_one(*session, make_document(kvp("title", "The Banshees of Inisherin"))); -}; - -// Call the with_transaction() method and pass in the callback function -// and an options object that sets the write concern for the transaction operations -try { - // Define an options instance to set the write concern for the transaction operations - options::transaction opts; - opts.write_concern(wc_majority); - - // Run and commit the insert operations defined in the callback function - session.with_transaction(callback, opts); -} catch (const mongocxx::exception& e) { - std::cout << "An exception occurred: " << e.what() << std::endl; - return EXIT_FAILURE; -} - -// Return the status of the transaction. This automatically calls the mongocxx::client_session destructor, -// closing the connection to the server. -return EXIT_SUCCESS; -// end-session diff --git a/source/includes/write/transactions.cpp b/source/includes/write/transactions.cpp new file mode 100644 index 00000000..91f9f26e --- /dev/null +++ b/source/includes/write/transactions.cpp @@ -0,0 +1,96 @@ +#include + +#include +#include +#include +#include +#include +#include + +using bsoncxx::builder::basic::kvp; +using bsoncxx::builder::basic::make_document; + +int main() { + + { + // start-with-transaction + + // Create a mongocxx::instance to initialize the drive and initialize a mongocxx::client + // using your MongoDB deployment connection string to establish a connection to the MongoDB server + mongocxx::instance instance{}; + mongocxx::client client(mongocxx::uri{""}); + + // Define database and collection variables + auto db = client["sample_mflix"]; + auto movies_collection = db["movies"]; + auto comments_collection = db["comments"]; + + // Start a client session + auto session = client.start_session(); + + // Define a callback function to specify 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", "Rhaenyra Targaryen"), kvp("text", "Dracarys II"))); + }; + + + try { + // Define an options instance to 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 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; + // end-with-transaction + } + { + // start-start-transaction + // Create a mongocxx::instance to initialize the drive and initialize a mongocxx::client + // using your MongoDB deployment connection string to establish a connection to the MongoDB server + mongocxx::instance instance{}; + mongocxx::client client(mongocxx::uri{""}); + + // Define database and collection variables + auto db = client["sample_mflix"]; + auto movies_collection = db["movies"]; + auto comments_collection = db["comments"]; + + // Start a client session + auto session = client.start_session(); + + try { + // Define an options instance to 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 transaction + session.start_transaction(); + + // Specify the series of database operations to perform during the transaction + movies_collection.insert_one(session, make_document(kvp("title", "Parasite"))); + comments_collection.insert_one(session, make_document(kvp("name", "Rhaenyra Targaryen"), kvp("text", "Dracarys II"))); + + // Commit the transaction + session.commit_transaction(); + } catch (const mongocxx::exception& e){ + std::cout << "An exception occurred: " << e.what() << std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; + // end-start-transaction + } +} + diff --git a/source/index.txt b/source/index.txt index 611d3fe5..39f8a176 100644 --- a/source/index.txt +++ b/source/index.txt @@ -16,7 +16,6 @@ MongoDB C++ Driver Write Data Indexes Aggregation - Transactions Security Specialized Data Formats C++17 Polyfill diff --git a/source/write.txt b/source/write.txt index 2b8c3a38..5d96a4a1 100644 --- a/source/write.txt +++ b/source/write.txt @@ -28,6 +28,7 @@ Write Data to MongoDB Delete Bulk Write GridFS + Transactions Overview -------- diff --git a/source/transactions.txt b/source/write/transactions.txt similarity index 51% rename from source/transactions.txt rename to source/write/transactions.txt index 98627a01..6417744f 100644 --- a/source/transactions.txt +++ b/source/write/transactions.txt @@ -29,33 +29,31 @@ before they ever become visible. In MongoDB, transactions run within logical **sessions**. A session is a grouping of related read or write operations that you intend to run sequentially. -Sessions enable causal consistency for a group of operations -or allow you to execute operations in an ACID transaction. MongoDB +Sessions enable causal consistency for a group of operations in an **ACID-compliant** transaction, which is a +transaction that meets an expectation of atomicity, consistency, isolation, and durability. MongoDB guarantees that the data involved in your transaction operations remains consistent, even if the operations encounter unexpected errors. -When using the {+driver-short+}, you can create a new session from a -``mongocxx::client`` instance as a ``mongocxx::client_session`` type. We recommend that you reuse -your client for multiple sessions and transactions instead of +When using the {+driver-short+}, you can create a new session from a ``mongocxx::client`` instance. +Then, you can use the resulting ``mongocxx::client_session`` instance to perform transactions. +We recommend that you reuse your client for multiple sessions and transactions instead of instantiating a new client each time. .. warning:: - Use a ``mongocxx::client_session`` only with the ``mongocxx::client`` (or associated - ``mongocxx::database`` or ``mongocxx::collection``) that created it. Using a - ``client_session`` with a different ``client`` results in operation - errors. + Use a ``mongocxx::client_session`` only with the ``mongocxx::client`` that created it. + Using a ``client_session`` with a different ``client`` results in operation errors. .. warning:: - Implementations of ``mongocxx::client_session`` are not thread-safe for concurrent use by multiple threads. + Each ``mongoxcc::client`` object and all of its child objects, including ``mongocxx::client_session``, should be used by a single thread at a time. + To learn more, see the :ref:`Thread and Fork Safety ` page. Methods ------- -After you start a session by using the ``start_session()`` method, you can modify -the session state by using the method set provided by the ``mongocxx::client_session`` interface. The -following table describes these methods: +To perform a transaction, you must first start a session by using the ``start_session()`` method. Then, you can +modify the session state using the following methods that are provided by the ``mongocxx::client_session`` interface: .. list-table:: :widths: 25 75 @@ -71,60 +69,56 @@ following table describes these methods: this method, see the :manual:`startTransaction() page ` in the Server manual. | - | **Parameter Type**: **Optional**. ``mongocxx::options::transaction`` - - * - ``abort_transcaction()`` - - | Ends the active transaction for this session. Returns an - error if there is no active transaction for the session or the - transaction has been committed or ended. To learn more about - this method, see the :manual:`abortTransaction() page - ` in the Server manual. - | - | **Parameter Type**: ``Context`` + | **Parameter Type**: ``stdx::optional`` * - ``commit_transaction()`` - | Commits the active transaction for this session. Returns an - error if there is no active transaction for the session or if the - transaction was ended. To learn more about + error if there is no active transaction for the session, if the transaction + was previously ended, or if there is a write conflict. To learn more about this method, see the :manual:`commitTransaction() page ` in the Server manual. | - | The ``CommitTransaction()`` method is an idempotent function, which - means that you can attempt to commit a transaction multiple times without changing data after the first successful commit. - A transaction can succeed but return an error with the - ``UnknownTransactionCommitResult`` label. If you rerun the - ``CommitTransaction()`` method after receiving this error, - your data is not changed by the repeat attempts. + | **Parameter Type**: None + * - ``abort_transcaction()`` + - | Ends the active transaction for this session. Returns an + error if there is no active transaction for the session or the + transaction has been committed or ended. To learn more about + this method, see the :manual:`abortTransaction() page + ` in the Server manual. | - | **Parameter Type**: ``Context`` + | **Parameter Type**: None * - ``with_transaction()`` - - | Starts a transaction on this session and runs the ``fn`` - callback. + - | Starts a new transaction on this client session, runs the provided callback function, + then commits the transaction. If it cannot commit the transaction, the entire sequence may be + retried, and the callback function may be run multiple times. + | Accepts a callback function as its first argument, which may contain a sequence of driver methods that run + operations against the server. | - | **Parameter Types**: ``callback``, ``transaction_opts`` + | **Parameter Types**: ``mongocxx::client_session::with_transaction_cb``, ``stdx::optional`` - * - ``~client_session()`` - - | Destructor for the ``mongocxx::client_session`` class. Ends any existing transactions and closes the session. - | - | **Parameter Type**: ``Context`` +The ``mongocxx::client_session`` interface also has methods to retrieve and modify session properties. +To learn more, see `mongocxx::client_session <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html>`__ in the API documentation. -The ``Session`` interface also has methods to retrieve session -properties and modify mutable session properties. Find more information -in the :ref:`API documentation `. +Examples +-------- +The {+driver-long+} provides a convenient transaction API to manage the transaction lifestyle. +To use this API, call the ``mongocxx::client_session::with_transaction()`` method. +The ``with_transaction()`` method performs the following tasks: -Example -------- +- Starts a new transaction on this client session +- Runs the provided callback function, handling errors by either ending the transaction or retrying the transaction sequence so that + the callback function may be run multiple times +- Commits the transaction -The following example shows how you can create a session, create a -transaction, and commit a multi-document insert operation through the -following steps: +The following example shows how you can use the ``with_transaction()`` method to +start and commit a transaction that performs a multi-document insert operation: -1. Create a session from the client using the ``start_session()`` method. -#. Create a callback function with the series of operations you want to +1. Start a session from the client using the ``start_session()`` method. +#. Define a callback function with the series of operations that you want to run in your transaction. -#. Define any options you want to add to your transaction. +#. Define any options that you want to add to your transaction. #. Call the ``with_transactions()`` method and pass in your callback function and options to start a transaction. The ``with_transactions()`` method executes and commits the transaction. If any operation results in @@ -132,15 +126,24 @@ errors, ``with_transactions()`` handles canceling the transaction. #. Return from your operation. This will automatically call the ``~end_session()`` destructor to close the transaction and client session. -.. literalinclude:: /includes/usage-examples/transactions.cpp +.. literalinclude:: /includes/write/transactions.cpp :language: cpp :dedent: - :start-after: start-session - :end-before: end-session + :start-after: start-with-transaction + :end-before: end-with-transaction -If you require more control over your transactions, you can find an example -showing how to manually create, commit, and end transactions in the -`full code example `__. + +If you want more control over your transactions, you can use the core API methods provided by the ``mongocxx::client_session`` class +to manually start, commit, and abort transactions. + +The following example shows how you can use the ``start_transaction()`` and ``commit_transaction()`` +methods to perform a transaction that executes a multi-document insert operation: + +.. literalinclude:: /includes/write/transactions.cpp + :language: cpp + :dedent: + :start-after: start-start-transaction + :end-before: end-start-transaction Additional Information ---------------------- @@ -149,14 +152,14 @@ To learn more about the concepts discussed in this guide, see the following page Server manual: - :manual:`Transactions ` -- :manual:`session ` -- :manual:`causal consistency ` +- :manual:`Server Sessions ` +- :manual:`Causal Consistency ` To learn more about ACID complicance, see the :website:`ACID Properties in Database Management Systems ` guide on the MongoDB website. -For more information about insert operations, see the -:ref:`Insert ` guide page. +To learn more about insert operations, see the +:ref:`Insert Documents ` guide. .. _api-docs-transaction: @@ -166,8 +169,8 @@ API Documentation To learn more about any of the types or methods discussed in this guide, see the following API Documentation: -- `mongocxx::client <{+api+}/classmongocxx_1_1client.html>`__ -- `mongocxx::client_session <{+api+}/mongocxx-3.3.2/classmongocxx_1_1client__session.html>`__ +- `mongocxx::client <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ +- `mongocxx::client_session <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html>`__ - `start_session() <{+api+}/classmongocxx_1_1v__noabi_1_1client.html#a03535128dbe5be973a08764b7741f24e>`__ - `start_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#a84ea5613813e6efbe065e3f39e1f972b>`__ - `abort_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#aabb8247a655741af6fe0f78bef8116e1>`__ From 97f573a46c64a3f2327fe33abe054cc56be73e6e Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Tue, 19 Nov 2024 10:59:50 -0500 Subject: [PATCH 08/32] (DOCSP-45012) Edits. --- source/includes/write/transactions.cpp | 9 +++--- source/write/transactions.txt | 43 ++++++++++++++------------ 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/source/includes/write/transactions.cpp b/source/includes/write/transactions.cpp index 91f9f26e..d1bac9c2 100644 --- a/source/includes/write/transactions.cpp +++ b/source/includes/write/transactions.cpp @@ -15,8 +15,7 @@ int main() { { // start-with-transaction - // Create a mongocxx::instance to initialize the drive and initialize a mongocxx::client - // using your MongoDB deployment connection string to establish a connection to the MongoDB server + // Establish a connection to the MongoDB deployment mongocxx::instance instance{}; mongocxx::client client(mongocxx::uri{""}); @@ -28,16 +27,16 @@ int main() { // Start a client session auto session = client.start_session(); - // Define a callback function to specify the sequence of operations to perform during the transaction + // 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", "Rhaenyra Targaryen"), kvp("text", "Dracarys II"))); + comments_collection.insert_one(*session, make_document(kvp("name", "Rhaenyra Targaryen"), kvp("text", "Dracarys."))); }; try { - // Define an options instance to set the write concern for the transaction operations + // Define an options instance to set the majority write concern for the transaction operations explicitly mongocxx::options::transaction opts; mongocxx::write_concern wc{}; wc.acknowledge_level(mongocxx::write_concern::level::k_majority); diff --git a/source/write/transactions.txt b/source/write/transactions.txt index 6417744f..f1676761 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -46,6 +46,7 @@ instantiating a new client each time. .. warning:: + Instances of ``mongocxx::client`` are not thread-safe. Each ``mongoxcc::client`` object and all of its child objects, including ``mongocxx::client_session``, should be used by a single thread at a time. To learn more, see the :ref:`Thread and Fork Safety ` page. @@ -53,7 +54,8 @@ Methods ------- To perform a transaction, you must first start a session by using the ``start_session()`` method. Then, you can -modify the session state using the following methods that are provided by the ``mongocxx::client_session`` interface: +modify the session state by using the method set provided by the ``mongocxx::client_session`` interface. +The following table describes these methods: .. list-table:: :widths: 25 75 @@ -78,7 +80,7 @@ modify the session state using the following methods that are provided by the `` this method, see the :manual:`commitTransaction() page ` in the Server manual. | - | **Parameter Type**: None + | **Parameter Type**: *None* * - ``abort_transcaction()`` - | Ends the active transaction for this session. Returns an @@ -87,44 +89,46 @@ modify the session state using the following methods that are provided by the `` this method, see the :manual:`abortTransaction() page ` in the Server manual. | - | **Parameter Type**: None + | **Parameter Type**: *None* * - ``with_transaction()`` - - | Starts a new transaction on this client session, runs the provided callback function, + - | Starts a new transaction on this client session, runs the provided callback, then commits the transaction. If it cannot commit the transaction, the entire sequence may be - retried, and the callback function may be run multiple times. - | Accepts a callback function as its first argument, which may contain a sequence of driver methods that run + retried, and the callback may be run multiple times. + | Accepts a callback as its first argument, which may contain a sequence of driver methods that run operations against the server. | | **Parameter Types**: ``mongocxx::client_session::with_transaction_cb``, ``stdx::optional`` The ``mongocxx::client_session`` interface also has methods to retrieve and modify session properties. -To learn more, see `mongocxx::client_session <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html>`__ in the API documentation. +To learn more, see the `mongocxx::client_session Class Reference<{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html>`__ page in the API documentation. Examples -------- -The {+driver-long+} provides a convenient transaction API to manage the transaction lifestyle. -To use this API, call the ``mongocxx::client_session::with_transaction()`` method. +The {+driver-long+} provides a convenient callback API to start, perform, and commit the transaction and handle any exceptions. +To use this API, call the ``with_transaction()`` method on your ``mongocxx::client_session`` instance and pass in a +callback specifying the sequence of operations you want to run in your transaction. The ``with_transaction()`` method performs the following tasks: - Starts a new transaction on this client session -- Runs the provided callback function, handling errors by either ending the transaction or retrying the transaction sequence so that - the callback function may be run multiple times +- Runs the provided callback, handling errors by either ending the transaction or retrying the transaction sequence - Commits the transaction The following example shows how you can use the ``with_transaction()`` method to start and commit a transaction that performs a multi-document insert operation: 1. Start a session from the client using the ``start_session()`` method. -#. Define a callback function with the series of operations that you want to -run in your transaction. -#. Define any options that you want to add to your transaction. -#. Call the ``with_transactions()`` method and pass in your callback function and -options to start a transaction. The ``with_transactions()`` method executes and -commits the transaction. If any operation results in -errors, ``with_transactions()`` handles canceling the transaction. +#. Define a callback specifying the series of operations that you want to + run in your transaction. The callback must take the current ``mongocxx::client_session`` as an argument + and pass it as a variable to all operations in the function body. +#. Define any options that you want to add to your transaction. For a full list of configurable options, + see the `mongocxx::options::transactions Class Reference <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ page in the API documentation. +#. Call the ``with_transactions()`` method and pass in your callback and + options to start a transaction. The ``with_transactions()`` method executes and + commits the transaction. If any operation results in + errors, ``with_transactions()`` handles canceling the transaction. #. Return from your operation. This will automatically call the ``~end_session()`` -destructor to close the transaction and client session. + destructor to close the transaction and client session. .. literalinclude:: /includes/write/transactions.cpp :language: cpp @@ -171,6 +175,7 @@ guide, see the following API Documentation: - `mongocxx::client <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ - `mongocxx::client_session <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html>`__ +- `mongocxx::options::transaction <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ - `start_session() <{+api+}/classmongocxx_1_1v__noabi_1_1client.html#a03535128dbe5be973a08764b7741f24e>`__ - `start_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#a84ea5613813e6efbe065e3f39e1f972b>`__ - `abort_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#aabb8247a655741af6fe0f78bef8116e1>`__ From 7fb6f64caa3716620983ac2c54106280164c2c29 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Tue, 19 Nov 2024 16:46:16 -0500 Subject: [PATCH 09/32] (DOCSP-45012) Edits. --- source/includes/write/transactions.cpp | 27 +++-- source/write/transactions.txt | 137 +++++++++++++------------ 2 files changed, 86 insertions(+), 78 deletions(-) diff --git a/source/includes/write/transactions.cpp b/source/includes/write/transactions.cpp index d1bac9c2..5503cbce 100644 --- a/source/includes/write/transactions.cpp +++ b/source/includes/write/transactions.cpp @@ -34,14 +34,13 @@ int main() { comments_collection.insert_one(*session, make_document(kvp("name", "Rhaenyra Targaryen"), kvp("text", "Dracarys."))); }; + // Define an options instance to set the majority write concern for the transaction operations explicitly + mongocxx::options::transaction opts; + mongocxx::write_concern wc{}; + wc.acknowledge_level(mongocxx::write_concern::level::k_majority); + opts.write_concern(wc); try { - // Define an options instance to set the majority write concern for the transaction operations explicitly - mongocxx::options::transaction opts; - mongocxx::write_concern wc{}; - wc.acknowledge_level(mongocxx::write_concern::level::k_majority); - opts.write_concern(wc); - // Start a transaction, execute the operations in the callback function, and commit the results session.with_transaction(callback, opts); } catch (const mongocxx::exception& e) { @@ -64,22 +63,22 @@ int main() { auto movies_collection = db["movies"]; auto comments_collection = db["comments"]; + // Define an options instance to prepare to set majority write explicitly + 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 { - // Define an options instance to 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 transaction - session.start_transaction(); + session.start_transaction(opts); // Specify the series of database operations to perform during the transaction movies_collection.insert_one(session, make_document(kvp("title", "Parasite"))); - comments_collection.insert_one(session, make_document(kvp("name", "Rhaenyra Targaryen"), kvp("text", "Dracarys II"))); + comments_collection.insert_one(session, make_document(kvp("name", "Rhaenyra Targaryen"), kvp("text", "Dracarys"))); // Commit the transaction session.commit_transaction(); diff --git a/source/write/transactions.txt b/source/write/transactions.txt index f1676761..06d3cbb8 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -47,88 +47,48 @@ instantiating a new client each time. .. warning:: Instances of ``mongocxx::client`` are not thread-safe. - Each ``mongoxcc::client`` object and all of its child objects, including ``mongocxx::client_session``, should be used by a single thread at a time. + Each ``mongoxcc::client`` instance and all of its child instances, including ``mongocxx::client_session``, should be used by a single thread at a time. To learn more, see the :ref:`Thread and Fork Safety ` page. -Methods -------- +Transaction APIs +---------------- -To perform a transaction, you must first start a session by using the ``start_session()`` method. Then, you can -modify the session state by using the method set provided by the ``mongocxx::client_session`` interface. -The following table describes these methods: - -.. list-table:: - :widths: 25 75 - :header-rows: 1 +The {+driver-long+} provides two transaction APIs to manage the transaction lifestyle. +Before you begin a transaction, you must call the ``start_session()`` method to instantiate a ``mongocxx::client_session``. +Then, you can either use the core API for manual control over your transaction, or use the +callback API for its convenient integrated error handling logic. - * - Method - - Description +The following sections describe how to use the callback API and core API to perform transactions. +To learn more about the callback API and the core API, see the :manual:`Drivers API ` page +in the {+mdb-{+mdb-server+}+} manual. - * - ``start_transaction()`` - - | Starts a new transaction, configured with the given options, on - the current client session. Returns an error if there is already - a transaction in progress for the session. To learn more about - this method, see the :manual:`startTransaction() page - ` in the Server manual. - | - | **Parameter Type**: ``stdx::optional`` +.. _cpp-callback-api: - * - ``commit_transaction()`` - - | Commits the active transaction for this session. Returns an - error if there is no active transaction for the session, if the transaction - was previously ended, or if there is a write conflict. To learn more about - this method, see the :manual:`commitTransaction() page - ` in the Server manual. - | - | **Parameter Type**: *None* +Callback API +~~~~~~~~~~~~ - * - ``abort_transcaction()`` - - | Ends the active transaction for this session. Returns an - error if there is no active transaction for the session or the - transaction has been committed or ended. To learn more about - this method, see the :manual:`abortTransaction() page - ` in the Server manual. - | - | **Parameter Type**: *None* - - * - ``with_transaction()`` - - | Starts a new transaction on this client session, runs the provided callback, - then commits the transaction. If it cannot commit the transaction, the entire sequence may be - retried, and the callback may be run multiple times. - | Accepts a callback as its first argument, which may contain a sequence of driver methods that run - operations against the server. - | - | **Parameter Types**: ``mongocxx::client_session::with_transaction_cb``, ``stdx::optional`` - -The ``mongocxx::client_session`` interface also has methods to retrieve and modify session properties. -To learn more, see the `mongocxx::client_session Class Reference<{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html>`__ page in the API documentation. - -Examples --------- -The {+driver-long+} provides a convenient callback API to start, perform, and commit the transaction and handle any exceptions. -To use this API, call the ``with_transaction()`` method on your ``mongocxx::client_session`` instance and pass in a +Use the callback API to start, execute, and commit the transaction with integrated error handling logic. +To implement this API, call the ``with_transaction()`` method on your ``mongocxx::client_session`` and pass in a callback specifying the sequence of operations you want to run in your transaction. The ``with_transaction()`` method performs the following tasks: - Starts a new transaction on this client session -- Runs the provided callback, handling errors by either ending the transaction or retrying the transaction sequence +- Runs the provided callback, automatically incorporating error handling logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` - Commits the transaction -The following example shows how you can use the ``with_transaction()`` method to +The following example shows how to use the ``with_transaction()`` method to start and commit a transaction that performs a multi-document insert operation: 1. Start a session from the client using the ``start_session()`` method. #. Define a callback specifying the series of operations that you want to run in your transaction. The callback must take the current ``mongocxx::client_session`` as an argument and pass it as a variable to all operations in the function body. -#. Define any options that you want to add to your transaction. For a full list of configurable options, +#. Define any options that you want to add to your transaction. For a full list of options, see the `mongocxx::options::transactions Class Reference <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ page in the API documentation. #. Call the ``with_transactions()`` method and pass in your callback and options to start a transaction. The ``with_transactions()`` method executes and commits the transaction. If any operation results in errors, ``with_transactions()`` handles canceling the transaction. -#. Return from your operation. This will automatically call the ``~end_session()`` - destructor to close the transaction and client session. .. literalinclude:: /includes/write/transactions.cpp :language: cpp @@ -136,12 +96,58 @@ start and commit a transaction that performs a multi-document insert operation: :start-after: start-with-transaction :end-before: end-with-transaction +.. _cpp-core-api: + +Core API +~~~~~~~~ + +Use the core API for more manual control of the transaction lifecycle. The core API doesn't incorporate error handling logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult``, +and instead provides the flexibility to incorporate custom error handling for these errors. To learn how to handle these errors, see the :manual:`Transaction Error Handling ` +section in the {+mdb-server+} manual. + +The core API requires explicit calls to start, commit, and abort the transaction using methods provided by the ``mongocxx::client_session`` interface. +The following table describes these methods: + +.. list-table:: + :widths: 25 75 + :header-rows: 1 + + * - Method + - Description + + * - ``start_transaction()`` + - | Starts a new transaction on the current client session. Accepts an optional ``mongocxx::options::transaction`` + instance as an argument to set options including read preference, read concern, and write concern. + | Throws an exception an error if the options are misconfigured, if there are network or other transient failures, or if there + are other errors such as a session with a transaction already in progress. + | To learn more about this method, see the :manual:`startTransaction() page + ` in the {+mdb-server+} manual. -If you want more control over your transactions, you can use the core API methods provided by the ``mongocxx::client_session`` class -to manually start, commit, and abort transactions. + * - ``commit_transaction()`` + - | Commits the active transaction on the current client session. + | Throws an exception if options are misconfigured, if there are network or other transient failures, + or if there are other errors such as a session with no transaction in progress. + | To learn more about this method, see the :manual:`commitTransaction() page + ` in the {+mdb-server+} manual. + + * - ``abort_transcaction()`` + - | Ends the active transaction on the current client session. + | Throws an exception if the options are misconfigured or if there are other errors such as + a session with no transaction in progress. + | To learn more about this method, see the :manual:`abortTransaction() page + ` in the {+mdb-server+} manual. + +The ``mongocxx::client_session`` class also provides methods to retrieve and modify session properties. +To learn more, see the `mongocxx::client_session Class Reference <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ page in the API documentation. -The following example shows how you can use the ``start_transaction()`` and ``commit_transaction()`` -methods to perform a transaction that executes a multi-document insert operation: +The following example shows how you can use the core API to perform a transaction that executes a multi-document insert operation that incorporates +logic to retry the transaction for transient errors and retry the commit for unknown commit error: + +1. Start a session from the client using the ``start_session()`` method. +#. Define any options that you want to add to your transaction. For a full list of options, + see the `mongocxx::options::transactions Class Reference <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ page in the API documentation. +#. Call any database operations that you want to run during your transaction. You must pass in the current ``client_session`` as an argument to each operation. +#. Commit the transaction using the ``commit_transaction()`` method .. literalinclude:: /includes/write/transactions.cpp :language: cpp @@ -149,14 +155,17 @@ methods to perform a transaction that executes a multi-document insert operation :start-after: start-start-transaction :end-before: end-start-transaction +Transaction Error Handling +-------------------------- + Additional Information ---------------------- To learn more about the concepts discussed in this guide, see the following pages in the -Server manual: +{+mdb-server+} manual: - :manual:`Transactions ` -- :manual:`Server Sessions ` +- :manual:`Server Sessions ` - :manual:`Causal Consistency ` To learn more about ACID complicance, see the :website:`ACID Properties in Database Management Systems ` From 5d151bc470a7273007a206869d07802f2da3bc81 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Tue, 19 Nov 2024 17:07:48 -0500 Subject: [PATCH 10/32] (DOCSP-45012) Edits. --- source/write/transactions.txt | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/source/write/transactions.txt b/source/write/transactions.txt index 06d3cbb8..4e95d80a 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -53,14 +53,12 @@ instantiating a new client each time. Transaction APIs ---------------- -The {+driver-long+} provides two transaction APIs to manage the transaction lifestyle. +The {+driver-long+} provides a callback API and a core API to manage the transaction lifestyle. Before you begin a transaction, you must call the ``start_session()`` method to instantiate a ``mongocxx::client_session``. -Then, you can either use the core API for manual control over your transaction, or use the -callback API for its convenient integrated error handling logic. +Then, you can choose one of the following APIs to perform your transaction: -The following sections describe how to use the callback API and core API to perform transactions. -To learn more about the callback API and the core API, see the :manual:`Drivers API ` page -in the {+mdb-{+mdb-server+}+} manual. +- :ref:`Callback API ` +- :ref:`Core API ` .. _cpp-callback-api: @@ -73,7 +71,7 @@ callback specifying the sequence of operations you want to run in your transacti The ``with_transaction()`` method performs the following tasks: - Starts a new transaction on this client session -- Runs the provided callback, automatically incorporating error handling logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` +- Runs the provided callback, automatically incorporating retry error handling logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` - Commits the transaction The following example shows how to use the ``with_transaction()`` method to @@ -96,13 +94,19 @@ start and commit a transaction that performs a multi-document insert operation: :start-after: start-with-transaction :end-before: end-with-transaction +.. tip:: + + To learn more about ``TransientTransactionError`` and ``UnknownTransactionCommitResult``, see the :manual:`Transaction Error Handling ` section in the + {+mdb-server+} manual. + + .. _cpp-core-api: Core API ~~~~~~~~ Use the core API for more manual control of the transaction lifecycle. The core API doesn't incorporate error handling logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult``, -and instead provides the flexibility to incorporate custom error handling for these errors. To learn how to handle these errors, see the :manual:`Transaction Error Handling ` +and instead provides the flexibility to incorporate custom error handling for these errors. To learn how to handle these errors, see the :manual:`Transaction Error Handling ` section in the {+mdb-server+} manual. The core API requires explicit calls to start, commit, and abort the transaction using methods provided by the ``mongocxx::client_session`` interface. @@ -167,6 +171,7 @@ To learn more about the concepts discussed in this guide, see the following page - :manual:`Transactions ` - :manual:`Server Sessions ` - :manual:`Causal Consistency ` +- :manual:`Transaction Error Handling ` To learn more about ACID complicance, see the :website:`ACID Properties in Database Management Systems ` guide on the MongoDB website. From ab493d66fd6c2a43f7d427cbe8377bfdd3dec372 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Wed, 20 Nov 2024 10:47:26 -0500 Subject: [PATCH 11/32] (DOCSP-45012) Edits. --- source/includes/write/transactions.cpp | 110 ++++++++++++++++++------- source/write/transactions.txt | 2 +- 2 files changed, 80 insertions(+), 32 deletions(-) diff --git a/source/includes/write/transactions.cpp b/source/includes/write/transactions.cpp index 5503cbce..8118fdd5 100644 --- a/source/includes/write/transactions.cpp +++ b/source/includes/write/transactions.cpp @@ -13,8 +13,7 @@ using bsoncxx::builder::basic::make_document; int main() { { - // start-with-transaction - + // start-callback-api // Establish a connection to the MongoDB deployment mongocxx::instance instance{}; mongocxx::client client(mongocxx::uri{""}); @@ -36,7 +35,7 @@ int main() { // Define an options instance to set the majority write concern for the transaction operations explicitly mongocxx::options::transaction opts; - mongocxx::write_concern wc{}; + mongocxx::write_concern wc; wc.acknowledge_level(mongocxx::write_concern::level::k_majority); opts.write_concern(wc); @@ -49,46 +48,95 @@ int main() { } return EXIT_SUCCESS; - // end-with-transaction + // end-callback-api } { - // start-start-transaction - // Create a mongocxx::instance to initialize the drive and initialize a mongocxx::client - // using your MongoDB deployment connection string to establish a connection to the MongoDB server + // start-core-api + // Establish a connection to the MongoDB deployment mongocxx::instance instance{}; mongocxx::client client(mongocxx::uri{""}); - // Define database and collection variables - auto db = client["sample_mflix"]; - auto movies_collection = db["movies"]; - auto comments_collection = db["comments"]; + // Define a function to handle TransientTransactionError retry logic + using transaction_func = std::function; + auto run_transaction_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; + } + } + } + }; - // Define an options instance to prepare to set majority write explicitly - mongocxx::options::transaction opts; - mongocxx::write_concern wc{}; - wc.acknowledge_level(mongocxx::write_concern::level::k_majority); - opts.write_concern(wc); + // Define a function to handle UnknownTransactionCommitResult retry logic + 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 operation ..." << std::endl; + continue; + } else { + std::cout << "Error during commit ..." << std::endl; + throw oe; + } + } + } + }; - // Start a client session - auto session = client.start_session(); + auto update_employee_info = [&](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 set the majority write concern for the transaction operations explicitly + mongocxx::options::transaction opts; + mongocxx::write_concern wc; + wc.acknowledge_level(mongocxx::write_concern::level::k_majority); + opts.write_concern(wc); - try { - // Start a transaction session.start_transaction(opts); - // Specify the series of database operations to perform during the transaction - movies_collection.insert_one(session, make_document(kvp("title", "Parasite"))); - comments_collection.insert_one(session, make_document(kvp("name", "Rhaenyra Targaryen"), kvp("text", "Dracarys"))); + try { + // Specify database operations to run during transaction + movies_collection.insert_one(session, make_document(kvp("title", "Parasite"))); + comments_collection.insert_one(session, make_document(kvp("name", "Rhaenyra Targaryen"), kvp("text", "Dracarys"))); + } catch (const mongocxx::operation_exception& oe) { + std::cout << "Caught exception during transaction, aborting." << std::endl; + session.abort_transaction(); + throw oe; + } + + commit_with_retry(session); + }; - // Commit the transaction - session.commit_transaction(); - } catch (const mongocxx::exception& e){ - std::cout << "An exception occurred: " << e.what() << std::endl; - return EXIT_FAILURE; + auto session = client.start_session(); + + try { + run_transaction_with_retry(update_employee_info, session); + } catch (const mongocxx::operation_exception& oe) { + // Do something with error. + throw oe; } - - return EXIT_SUCCESS; - // end-start-transaction + // end-core-api } + + + } diff --git a/source/write/transactions.txt b/source/write/transactions.txt index 4e95d80a..352eb444 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -124,7 +124,7 @@ The following table describes these methods: instance as an argument to set options including read preference, read concern, and write concern. | Throws an exception an error if the options are misconfigured, if there are network or other transient failures, or if there are other errors such as a session with a transaction already in progress. - | To learn more about this method, see the :manual:`startTransaction() page + | To learn more about this method, see the :manual:`startTransaction() page ` in the {+mdb-server+} manual. * - ``commit_transaction()`` From 93742f59c0e9a62b8625cca284807ea9c2256a42 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Wed, 20 Nov 2024 11:03:04 -0500 Subject: [PATCH 12/32] (DOCSP-45012) Edits. --- source/includes/write/transactions.cpp | 2 +- source/write/transactions.txt | 15 ++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/source/includes/write/transactions.cpp b/source/includes/write/transactions.cpp index 8118fdd5..2dd8cbeb 100644 --- a/source/includes/write/transactions.cpp +++ b/source/includes/write/transactions.cpp @@ -96,7 +96,7 @@ int main() { } }; - auto update_employee_info = [&](mongocxx::client_session& session) { + auto transaction_operations = [&](mongocxx::client_session& session) { auto& client = session.client(); // Define database and collection variables diff --git a/source/write/transactions.txt b/source/write/transactions.txt index 352eb444..fa7d6bf4 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -91,8 +91,8 @@ start and commit a transaction that performs a multi-document insert operation: .. literalinclude:: /includes/write/transactions.cpp :language: cpp :dedent: - :start-after: start-with-transaction - :end-before: end-with-transaction + :start-after: start-callback-api + :end-before: end-callback-api .. tip:: @@ -156,11 +156,8 @@ logic to retry the transaction for transient errors and retry the commit for unk .. literalinclude:: /includes/write/transactions.cpp :language: cpp :dedent: - :start-after: start-start-transaction - :end-before: end-start-transaction - -Transaction Error Handling --------------------------- + :start-after: start-core-api + :end-before: end-core-api Additional Information ---------------------- @@ -169,6 +166,7 @@ To learn more about the concepts discussed in this guide, see the following page {+mdb-server+} manual: - :manual:`Transactions ` +- :manual:`Drivers API ` - :manual:`Server Sessions ` - :manual:`Causal Consistency ` - :manual:`Transaction Error Handling ` @@ -176,8 +174,7 @@ To learn more about the concepts discussed in this guide, see the following page To learn more about ACID complicance, see the :website:`ACID Properties in Database Management Systems ` guide on the MongoDB website. -To learn more about insert operations, see the -:ref:`Insert Documents ` guide. +To learn more about insert operations, see the :ref:`Insert Documents ` guide. .. _api-docs-transaction: From acf1eda9370ad8e7b72087376d28a38337c0d1aa Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Wed, 20 Nov 2024 13:46:15 -0500 Subject: [PATCH 13/32] (DOCSP-45012) Editing instructions for transactions. --- source/includes/write/transactions.cpp | 11 ++++++----- source/write/transactions.txt | 23 ++++++++++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/source/includes/write/transactions.cpp b/source/includes/write/transactions.cpp index 2dd8cbeb..604d38e8 100644 --- a/source/includes/write/transactions.cpp +++ b/source/includes/write/transactions.cpp @@ -6,6 +6,7 @@ #include #include #include +#include using bsoncxx::builder::basic::kvp; using bsoncxx::builder::basic::make_document; @@ -56,9 +57,9 @@ int main() { mongocxx::instance instance{}; mongocxx::client client(mongocxx::uri{""}); - // Define a function to handle TransientTransactionError retry logic + // Incorporate TransientTransactionError retry logic using transaction_func = std::function; - auto run_transaction_with_retry = [](transaction_func txn_func, mongocxx::client_session& session) { + auto run_with_retry = [](transaction_func txn_func, mongocxx::client_session& session) { while (true) { try { txn_func(session); // performs transaction. @@ -76,7 +77,7 @@ int main() { } }; - // Define a function to handle UnknownTransactionCommitResult retry logic + // Incorporate UnknownTransactionCommitResult retry logic auto commit_with_retry = [](mongocxx::client_session& session) { while (true) { try { @@ -96,7 +97,7 @@ int main() { } }; - auto transaction_operations = [&](mongocxx::client_session& session) { + auto txn_operations = [&](mongocxx::client_session& session) { auto& client = session.client(); // Define database and collection variables @@ -128,7 +129,7 @@ int main() { auto session = client.start_session(); try { - run_transaction_with_retry(update_employee_info, session); + run_transaction_with_retry(txn_operations, session); } catch (const mongocxx::operation_exception& oe) { // Do something with error. throw oe; diff --git a/source/write/transactions.txt b/source/write/transactions.txt index fa7d6bf4..98249f6e 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -147,11 +147,24 @@ To learn more, see the `mongocxx::client_session Class Reference <{+api+}/classm The following example shows how you can use the core API to perform a transaction that executes a multi-document insert operation that incorporates logic to retry the transaction for transient errors and retry the commit for unknown commit error: -1. Start a session from the client using the ``start_session()`` method. -#. Define any options that you want to add to your transaction. For a full list of options, - see the `mongocxx::options::transactions Class Reference <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ page in the API documentation. -#. Call any database operations that you want to run during your transaction. You must pass in the current ``client_session`` as an argument to each operation. -#. Commit the transaction using the ``commit_transaction()`` method + +1. Define a wrapper function called ``run_with_retry`` that runs your transaction with incorporated retry logic for ``UnknownTransactionCommitResult`` + + .. Define a wrapper function that accepts as its argument a function that starts and runs your transaction + .. The wrapper function runs this function and incorporates retry logic for ``TransientTransactionError`` +#. Define a wrapper function called ``commit_with_retry`` that commits your transaction with incorporated retry logic for ``UnknownTransactionCommitResult`` + + .. Define a wrapper function that accepts as its argument a session with an active transaction + .. This wrapper function commits this transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` +#. Define a function called ``txn_operations`` that starts, executes, and commits a transaction through the following steps: + - Define any options that you want to add to your transaction. For a full list of options, + see the `mongocxx::options::transactions Class Reference <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ page in the API documentation. + - Call the ``start_transaction()`` method to start your transaction. + - Using a ``try`` and ``catch`` block, try the series of database operations you want to perform during the transaction and call the ``abort_transaction()`` method + to abort your transaction when an exception is caught. + - Call your ``comit_with_retry`` wrapper function and pass in your current session to commit your active transaction. +#. Start a session from the client using the ``start_session()`` method +#. Call your ``run_with_retry`` wrapper function and pass in your ``txn_operations`` function to start, execute, and commit your transaction. .. literalinclude:: /includes/write/transactions.cpp :language: cpp From cec82eb09bfaf5acfdabae5b2f8386e8b71f83b1 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Wed, 20 Nov 2024 14:12:28 -0500 Subject: [PATCH 14/32] (DOCSP-45012) Edits. --- source/write/transactions.txt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/write/transactions.txt b/source/write/transactions.txt index 98249f6e..73fc76bf 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -144,15 +144,14 @@ The following table describes these methods: The ``mongocxx::client_session`` class also provides methods to retrieve and modify session properties. To learn more, see the `mongocxx::client_session Class Reference <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ page in the API documentation. -The following example shows how you can use the core API to perform a transaction that executes a multi-document insert operation that incorporates +The following example shows how you can use the core API to perform a transaction that incorporates logic to retry the transaction for transient errors and retry the commit for unknown commit error: - -1. Define a wrapper function called ``run_with_retry`` that runs your transaction with incorporated retry logic for ``UnknownTransactionCommitResult`` +1. Define a wrapper function called ``run_with_retry`` that runs your transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` .. Define a wrapper function that accepts as its argument a function that starts and runs your transaction .. The wrapper function runs this function and incorporates retry logic for ``TransientTransactionError`` -#. Define a wrapper function called ``commit_with_retry`` that commits your transaction with incorporated retry logic for ``UnknownTransactionCommitResult`` +#. Define a wrapper function called ``commit_with_retry`` that commits your transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` .. Define a wrapper function that accepts as its argument a session with an active transaction .. This wrapper function commits this transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` From 50213c055b3cc636eaf6ba104251d28d9b343005 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Wed, 20 Nov 2024 14:13:23 -0500 Subject: [PATCH 15/32] (DOCSP-45012) Formatting. --- source/write/transactions.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/source/write/transactions.txt b/source/write/transactions.txt index 73fc76bf..75db7eb4 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -156,6 +156,7 @@ logic to retry the transaction for transient errors and retry the commit for unk .. Define a wrapper function that accepts as its argument a session with an active transaction .. This wrapper function commits this transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` #. Define a function called ``txn_operations`` that starts, executes, and commits a transaction through the following steps: + - Define any options that you want to add to your transaction. For a full list of options, see the `mongocxx::options::transactions Class Reference <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ page in the API documentation. - Call the ``start_transaction()`` method to start your transaction. From e105e2ec6f007853cac1cc3fcdb715a425ad0f9b Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Wed, 20 Nov 2024 14:14:39 -0500 Subject: [PATCH 16/32] (DOCSP-45012) Wording. --- source/write/transactions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/write/transactions.txt b/source/write/transactions.txt index 75db7eb4..52184976 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -155,7 +155,7 @@ logic to retry the transaction for transient errors and retry the commit for unk .. Define a wrapper function that accepts as its argument a session with an active transaction .. This wrapper function commits this transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` -#. Define a function called ``txn_operations`` that starts, executes, and commits a transaction through the following steps: +#. Define a function called ``txn_operations`` that performs a transaction using the following steps: - Define any options that you want to add to your transaction. For a full list of options, see the `mongocxx::options::transactions Class Reference <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ page in the API documentation. From 490de3c2b839e39db63f33859322c769af3a5384 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Wed, 20 Nov 2024 17:11:41 -0500 Subject: [PATCH 17/32] (DOCSP-45012) Edit introduction to code examples. --- source/includes/write/transactions.cpp | 7 ++- source/write/transactions.txt | 76 +++++++++++++++----------- 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/source/includes/write/transactions.cpp b/source/includes/write/transactions.cpp index 604d38e8..c4f6189a 100644 --- a/source/includes/write/transactions.cpp +++ b/source/includes/write/transactions.cpp @@ -24,9 +24,6 @@ int main() { auto movies_collection = db["movies"]; auto comments_collection = db["comments"]; - // Start a client session - auto session = client.start_session(); - // 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. @@ -40,6 +37,9 @@ int main() { 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); @@ -126,6 +126,7 @@ int main() { commit_with_retry(session); }; + // Start a client session auto session = client.start_session(); try { diff --git a/source/write/transactions.txt b/source/write/transactions.txt index 52184976..bc362086 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -44,7 +44,7 @@ instantiating a new client each time. Use a ``mongocxx::client_session`` only with the ``mongocxx::client`` that created it. Using a ``client_session`` with a different ``client`` results in operation errors. -.. warning:: +.. important:: Instances of ``mongocxx::client`` are not thread-safe. Each ``mongoxcc::client`` instance and all of its child instances, including ``mongocxx::client_session``, should be used by a single thread at a time. @@ -60,6 +60,8 @@ Then, you can choose one of the following APIs to perform your transaction: - :ref:`Callback API ` - :ref:`Core API ` +To learn more about when to use each transaction API, see the :manual:`Drivers API ` page in the {+mdb-server+} manual. + .. _cpp-callback-api: Callback API @@ -71,22 +73,25 @@ callback specifying the sequence of operations you want to run in your transacti The ``with_transaction()`` method performs the following tasks: - Starts a new transaction on this client session -- Runs the provided callback, automatically incorporating retry error handling logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` +- Runs the provided callback, automatically incorporating retry logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` - Commits the transaction -The following example shows how to use the ``with_transaction()`` method to -start and commit a transaction that performs a multi-document insert operation: +The following code example shows how to use the callback API to perform a transaction. +When run, the code performs the following actions: + +1. Starts a session from the client using the ``start_session()`` method. +#. Defines a callback function that inserts documents into collections from the ``sample_mflix`` database. +#. Configures an option object to set the write preference for the transaction operations. +#. Calls the ``with_transactions()`` method to manage the transaction, passing the callback and client session as arguments. -1. Start a session from the client using the ``start_session()`` method. -#. Define a callback specifying the series of operations that you want to - run in your transaction. The callback must take the current ``mongocxx::client_session`` as an argument - and pass it as a variable to all operations in the function body. -#. Define any options that you want to add to your transaction. For a full list of options, - see the `mongocxx::options::transactions Class Reference <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ page in the API documentation. -#. Call the ``with_transactions()`` method and pass in your callback and - options to start a transaction. The ``with_transactions()`` method executes and - commits the transaction. If any operation results in - errors, ``with_transactions()`` handles canceling the transaction. +.. 1. Starts a session from the client using the ``start_session()`` method. +.. #. Defines a callback specifying the series of operations to run in the transaction. +.. The callback takes the current ``mongocxx::client_session`` as an argument +.. and passes it as a variable to all operations in the function body. +.. #. Defines a ``mongocxx::options::transactions`` instance to set the write preference for the transaction operations. +.. #. Calls the ``with_transactions()`` method and passes in the callback and +.. options to start a transaction, execute the operations specified in the callback, and commit the transaction. +.. The ``with_transactions()`` method automatically raises any exceptions and incorporates retry logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult``. .. literalinclude:: /includes/write/transactions.cpp :language: cpp @@ -144,27 +149,35 @@ The following table describes these methods: The ``mongocxx::client_session`` class also provides methods to retrieve and modify session properties. To learn more, see the `mongocxx::client_session Class Reference <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ page in the API documentation. -The following example shows how you can use the core API to perform a transaction that incorporates -logic to retry the transaction for transient errors and retry the commit for unknown commit error: +The following code example shows how to use the core API to perform a transaction. +When run, the code performs the following actions: + +1. Starts a session from the client using the ``start_session()`` method. +#. Calls the ``start_transaction()`` method to start a transaction +#. Attempts to insert documents into collections from the ``sample_mflix`` database. + If an operation encounters an error, the transaction is aborted using the ``abort_transaction()`` method + and then retried if the error has the label ``TransientTransactionError``. +#. Calls the ``commit_transaction()`` method to commit the active transaction. If the commit encounters an error with the label ``UnknownTransactionCommitResult``, the commit is retried. + -1. Define a wrapper function called ``run_with_retry`` that runs your transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` +.. 1. Define a wrapper function called ``run_with_retry`` that runs your transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` - .. Define a wrapper function that accepts as its argument a function that starts and runs your transaction - .. The wrapper function runs this function and incorporates retry logic for ``TransientTransactionError`` -#. Define a wrapper function called ``commit_with_retry`` that commits your transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` +.. .. Define a wrapper function that accepts as its argument a function that starts and runs your transaction +.. .. The wrapper function runs this function and incorporates retry logic for ``TransientTransactionError`` +.. #. Define a wrapper function called ``commit_with_retry`` that commits your transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` - .. Define a wrapper function that accepts as its argument a session with an active transaction - .. This wrapper function commits this transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` -#. Define a function called ``txn_operations`` that performs a transaction using the following steps: +.. .. Define a wrapper function that accepts as its argument a session with an active transaction +.. .. This wrapper function commits this transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` +.. #. Define a function called ``txn_operations`` that performs a transaction using the following steps: - - Define any options that you want to add to your transaction. For a full list of options, - see the `mongocxx::options::transactions Class Reference <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ page in the API documentation. - - Call the ``start_transaction()`` method to start your transaction. - - Using a ``try`` and ``catch`` block, try the series of database operations you want to perform during the transaction and call the ``abort_transaction()`` method - to abort your transaction when an exception is caught. - - Call your ``comit_with_retry`` wrapper function and pass in your current session to commit your active transaction. -#. Start a session from the client using the ``start_session()`` method -#. Call your ``run_with_retry`` wrapper function and pass in your ``txn_operations`` function to start, execute, and commit your transaction. +.. - Define any options that you want to add to your transaction. For a full list of options, +.. see the `mongocxx::options::transactions Class Reference <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ page in the API documentation. +.. - Call the ``start_transaction()`` method to start your transaction. +.. - Using a ``try`` and ``catch`` block, try the series of database operations you want to perform during the transaction and call the ``abort_transaction()`` method +.. to abort your transaction when an exception is caught. +.. - Call your ``comit_with_retry`` wrapper function and pass in your current session to commit your active transaction. +.. #. Start a session from the client using the ``start_session()`` method +.. #. Call your ``run_with_retry`` wrapper function and pass in your ``txn_operations`` function to start, execute, and commit your transaction. .. literalinclude:: /includes/write/transactions.cpp :language: cpp @@ -182,7 +195,6 @@ To learn more about the concepts discussed in this guide, see the following page - :manual:`Drivers API ` - :manual:`Server Sessions ` - :manual:`Causal Consistency ` -- :manual:`Transaction Error Handling ` To learn more about ACID complicance, see the :website:`ACID Properties in Database Management Systems ` guide on the MongoDB website. From 06ca58bee2c8457c97eb4c7174ebaadf6d0ea2ca Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Wed, 20 Nov 2024 17:18:42 -0500 Subject: [PATCH 18/32] (DOCSP-45012) Edit. --- source/write/transactions.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/write/transactions.txt b/source/write/transactions.txt index bc362086..491e3512 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -80,7 +80,7 @@ The following code example shows how to use the callback API to perform a transa When run, the code performs the following actions: 1. Starts a session from the client using the ``start_session()`` method. -#. Defines a callback function that inserts documents into collections from the ``sample_mflix`` database. +#. Defines a callback function that inserts documents into collections in the ``sample_mflix`` database. #. Configures an option object to set the write preference for the transaction operations. #. Calls the ``with_transactions()`` method to manage the transaction, passing the callback and client session as arguments. @@ -154,7 +154,7 @@ When run, the code performs the following actions: 1. Starts a session from the client using the ``start_session()`` method. #. Calls the ``start_transaction()`` method to start a transaction -#. Attempts to insert documents into collections from the ``sample_mflix`` database. +#. Attempts to insert documents into collections in the ``sample_mflix`` database. If an operation encounters an error, the transaction is aborted using the ``abort_transaction()`` method and then retried if the error has the label ``TransientTransactionError``. #. Calls the ``commit_transaction()`` method to commit the active transaction. If the commit encounters an error with the label ``UnknownTransactionCommitResult``, the commit is retried. From d18abff283c5e2c8321e5d800b49dfe9cb40a830 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Thu, 21 Nov 2024 11:32:21 -0500 Subject: [PATCH 19/32] (DOCSP-45012) Edits. --- source/includes/write/transactions.cpp | 8 +- source/write/transactions.txt | 131 ++++++++++--------------- 2 files changed, 58 insertions(+), 81 deletions(-) diff --git a/source/includes/write/transactions.cpp b/source/includes/write/transactions.cpp index c4f6189a..b8ee6006 100644 --- a/source/includes/write/transactions.cpp +++ b/source/includes/write/transactions.cpp @@ -97,7 +97,7 @@ int main() { } }; - auto txn_operations = [&](mongocxx::client_session& session) { + auto run_transaction = [&](mongocxx::client_session& session) { auto& client = session.client(); // Define database and collection variables @@ -113,8 +113,8 @@ int main() { session.start_transaction(opts); + // Attempt to insert documents into database collections try { - // Specify database operations to run during transaction movies_collection.insert_one(session, make_document(kvp("title", "Parasite"))); comments_collection.insert_one(session, make_document(kvp("name", "Rhaenyra Targaryen"), kvp("text", "Dracarys"))); } catch (const mongocxx::operation_exception& oe) { @@ -130,9 +130,9 @@ int main() { auto session = client.start_session(); try { - run_transaction_with_retry(txn_operations, session); + run_transaction_with_retry(run_transaction, session); } catch (const mongocxx::operation_exception& oe) { - // Do something with error. + // Do something with error throw oe; } // end-core-api diff --git a/source/write/transactions.txt b/source/write/transactions.txt index 491e3512..0d56d2a2 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -55,43 +55,35 @@ Transaction APIs The {+driver-long+} provides a callback API and a core API to manage the transaction lifestyle. Before you begin a transaction, you must call the ``start_session()`` method to instantiate a ``mongocxx::client_session``. -Then, you can choose one of the following APIs to perform your transaction: +Then, you can choose a transaction API to start, exeecute, and commit your transaction. -- :ref:`Callback API ` -- :ref:`Core API ` - -To learn more about when to use each transaction API, see the :manual:`Drivers API ` page in the {+mdb-server+} manual. +The following sections show how to use the callback API and the core API to manage the transaction lifecycle. +To learn more about transaction APIs, see the :manual:`Drivers API ` page in the {+mdb-server+} manual. .. _cpp-callback-api: Callback API ~~~~~~~~~~~~ -Use the callback API to start, execute, and commit the transaction with integrated error handling logic. +Use the callback API to start a transaction, execute specified database operations, and commit the transaction with +incorporated retry logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` errors. +Use the callback API to start, execute, and commit the transaction with automatically incorporated error handling logic. To implement this API, call the ``with_transaction()`` method on your ``mongocxx::client_session`` and pass in a callback specifying the sequence of operations you want to run in your transaction. -The ``with_transaction()`` method performs the following tasks: +.. The ``with_transaction()`` method performs the following tasks: -- Starts a new transaction on this client session -- Runs the provided callback, automatically incorporating retry logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` -- Commits the transaction +.. - Starts a new transaction on this client session +.. - Runs the provided callback, automatically incorporating retry logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` +.. - Commits the transaction -The following code example shows how to use the callback API to perform a transaction. +The following code shows how to use the callback API to perform a transaction. When run, the code performs the following actions: 1. Starts a session from the client using the ``start_session()`` method. -#. Defines a callback function that inserts documents into collections in the ``sample_mflix`` database. -#. Configures an option object to set the write preference for the transaction operations. -#. Calls the ``with_transactions()`` method to manage the transaction, passing the callback and client session as arguments. - -.. 1. Starts a session from the client using the ``start_session()`` method. -.. #. Defines a callback specifying the series of operations to run in the transaction. -.. The callback takes the current ``mongocxx::client_session`` as an argument -.. and passes it as a variable to all operations in the function body. -.. #. Defines a ``mongocxx::options::transactions`` instance to set the write preference for the transaction operations. -.. #. Calls the ``with_transactions()`` method and passes in the callback and -.. options to start a transaction, execute the operations specified in the callback, and commit the transaction. -.. The ``with_transactions()`` method automatically raises any exceptions and incorporates retry logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult``. +#. Defines a callback function that specifies the database operations to perform during the transaction. + These operations insert documents into collections in the ``sample_mflix`` database. +#. Creates an option object to set the write preference for the transaction operations. +#. Calls the ``with_transactions()`` method to manage the transaction, passing the callback and option object as arguments. .. literalinclude:: /includes/write/transactions.cpp :language: cpp @@ -99,20 +91,14 @@ When run, the code performs the following actions: :start-after: start-callback-api :end-before: end-callback-api -.. tip:: - - To learn more about ``TransientTransactionError`` and ``UnknownTransactionCommitResult``, see the :manual:`Transaction Error Handling ` section in the - {+mdb-server+} manual. - - .. _cpp-core-api: Core API ~~~~~~~~ -Use the core API for more manual control of the transaction lifecycle. The core API doesn't incorporate error handling logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult``, -and instead provides the flexibility to incorporate custom error handling for these errors. To learn how to handle these errors, see the :manual:`Transaction Error Handling ` -section in the {+mdb-server+} manual. +Use the core API for more control of the transaction lifecycle. The core API doesn't incorporate error handling logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult``, +and instead provides the flexibility to incorporate custom error handling for these errors. To learn more about how to handle ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` errors, +see the :manual:`Transaction Error Handling ` section in the {+mdb-server+} manual. The core API requires explicit calls to start, commit, and abort the transaction using methods provided by the ``mongocxx::client_session`` interface. The following table describes these methods: @@ -126,59 +112,51 @@ The following table describes these methods: * - ``start_transaction()`` - | Starts a new transaction on the current client session. Accepts an optional ``mongocxx::options::transaction`` - instance as an argument to set options including read preference, read concern, and write concern. - | Throws an exception an error if the options are misconfigured, if there are network or other transient failures, or if there - are other errors such as a session with a transaction already in progress. - | To learn more about this method, see the :manual:`startTransaction() page - ` in the {+mdb-server+} manual. + instance as an argument to set options. For a full list of options, see the `mongocxx::options::transaction <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ + API documentation. + | + | Raises an exception if the options are misconfigured, if there are network or other transient failures, or if there + are other errors such as a session with a transaction already in progress. If an error is returned with the ``TransientTransactionError`` label, + you can end the transaction and then retry it with the expectation that it will succeed. + | + | To learn more about this method, see the :manual:`startTransaction() + ` guide in the {+mdb-server+} manual. * - ``commit_transaction()`` - | Commits the active transaction on the current client session. - | Throws an exception if options are misconfigured, if there are network or other transient failures, - or if there are other errors such as a session with no transaction in progress. - | To learn more about this method, see the :manual:`commitTransaction() page - ` in the {+mdb-server+} manual. + | + | Raises an exception if options are misconfigured, if there are network or other transient failures, + or if there are other errors such as a session with no transaction in progress. If an error is returned with the ``UnknownTransactionCommitResult`` label, + you can end the transaction and then retry it with the expectation that it will succeed when the committed transaction satisfies the set write concern. + | + | To learn more about this method, see the :manual:`commitTransaction() + ` guide in the {+mdb-server+} manual. * - ``abort_transcaction()`` - | Ends the active transaction on the current client session. - | Throws an exception if the options are misconfigured or if there are other errors such as + | + | Raises an exception if the options are misconfigured or if there are other errors such as a session with no transaction in progress. - | To learn more about this method, see the :manual:`abortTransaction() page - ` in the {+mdb-server+} manual. + | + | To learn more about this method, see the :manual:`abortTransaction() + ` guide in the {+mdb-server+} manual. -The ``mongocxx::client_session`` class also provides methods to retrieve and modify session properties. -To learn more, see the `mongocxx::client_session Class Reference <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ page in the API documentation. +.. tip:: + + The ``mongocxx::client_session`` class also provides methods to retrieve and modify session properties. + To learn more, see the `mongocxx::client_session <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ API documentation. -The following code example shows how to use the core API to perform a transaction. +The following code shows how to use the core API to perform a transaction. When run, the code performs the following actions: 1. Starts a session from the client using the ``start_session()`` method. -#. Calls the ``start_transaction()`` method to start a transaction +#. Creates an option object to set the write preference for the transaction operations. +#. Calls the ``start_transaction()`` method to start a transaction, passing in the option object as an argument. #. Attempts to insert documents into collections in the ``sample_mflix`` database. - If an operation encounters an error, the transaction is aborted using the ``abort_transaction()`` method - and then retried if the error has the label ``TransientTransactionError``. + If an operation encounters an error, the transaction is aborted and + then retried if the error has the label ``TransientTransactionError``. #. Calls the ``commit_transaction()`` method to commit the active transaction. If the commit encounters an error with the label ``UnknownTransactionCommitResult``, the commit is retried. - -.. 1. Define a wrapper function called ``run_with_retry`` that runs your transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` - -.. .. Define a wrapper function that accepts as its argument a function that starts and runs your transaction -.. .. The wrapper function runs this function and incorporates retry logic for ``TransientTransactionError`` -.. #. Define a wrapper function called ``commit_with_retry`` that commits your transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` - -.. .. Define a wrapper function that accepts as its argument a session with an active transaction -.. .. This wrapper function commits this transaction and incorporates retry logic for ``UnknownTransactionCommitResult`` -.. #. Define a function called ``txn_operations`` that performs a transaction using the following steps: - -.. - Define any options that you want to add to your transaction. For a full list of options, -.. see the `mongocxx::options::transactions Class Reference <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ page in the API documentation. -.. - Call the ``start_transaction()`` method to start your transaction. -.. - Using a ``try`` and ``catch`` block, try the series of database operations you want to perform during the transaction and call the ``abort_transaction()`` method -.. to abort your transaction when an exception is caught. -.. - Call your ``comit_with_retry`` wrapper function and pass in your current session to commit your active transaction. -.. #. Start a session from the client using the ``start_session()`` method -.. #. Call your ``run_with_retry`` wrapper function and pass in your ``txn_operations`` function to start, execute, and commit your transaction. - .. literalinclude:: /includes/write/transactions.cpp :language: cpp :dedent: @@ -192,8 +170,8 @@ To learn more about the concepts discussed in this guide, see the following page {+mdb-server+} manual: - :manual:`Transactions ` -- :manual:`Drivers API ` -- :manual:`Server Sessions ` +- :manual:`Drivers API ` +- :manual:`Server Sessions ` - :manual:`Causal Consistency ` To learn more about ACID complicance, see the :website:`ACID Properties in Database Management Systems ` @@ -211,11 +189,10 @@ guide, see the following API Documentation: - `mongocxx::client <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ - `mongocxx::client_session <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html>`__ -- `mongocxx::options::transaction <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ +- `mongocxx::options::transaction <{+api+}/classmongocxx_1_1options_1_1transaction.html>`__ - `start_session() <{+api+}/classmongocxx_1_1v__noabi_1_1client.html#a03535128dbe5be973a08764b7741f24e>`__ +- `with_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#a3dcdf91bf72e69bf7e63a7c8ad859b93>`__ - `start_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#a84ea5613813e6efbe065e3f39e1f972b>`__ -- `abort_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#aabb8247a655741af6fe0f78bef8116e1>`__ - `commit_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#ad2d1a8f7c77542db6ec7629d162761ff>`__ -- `with_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#a3dcdf91bf72e69bf7e63a7c8ad859b93>`__ -- `insert_one() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#af040f1fcb1ac406037bf1cbcdb300061>`__ -- `insert_many() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#a61ebaa0c63296761637ce45115512085>`__ \ No newline at end of file +- `abort_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#aabb8247a655741af6fe0f78bef8116e1>`__ +- `insert_one() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#a839bedb5505e5ce75cbf384e2e2457bd>`__ \ No newline at end of file From fd6a0eb11d0409de791ad18fa91cc582d9bbee01 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Thu, 21 Nov 2024 11:51:17 -0500 Subject: [PATCH 20/32] (DOCSP-45012) Edits> --- source/write/transactions.txt | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/source/write/transactions.txt b/source/write/transactions.txt index 0d56d2a2..a4f46708 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -55,9 +55,11 @@ Transaction APIs The {+driver-long+} provides a callback API and a core API to manage the transaction lifestyle. Before you begin a transaction, you must call the ``start_session()`` method to instantiate a ``mongocxx::client_session``. -Then, you can choose a transaction API to start, exeecute, and commit your transaction. +Then, you can choose one of the following transaction APIs to perform a transaction: + +- Callback API +- Core API -The following sections show how to use the callback API and the core API to manage the transaction lifecycle. To learn more about transaction APIs, see the :manual:`Drivers API ` page in the {+mdb-server+} manual. .. _cpp-callback-api: @@ -65,25 +67,24 @@ To learn more about transaction APIs, see the :manual:`Drivers API ` section in the {+mdb-server+} manual. @@ -144,15 +145,15 @@ The following table describes these methods: .. tip:: The ``mongocxx::client_session`` class also provides methods to retrieve and modify session properties. - To learn more, see the `mongocxx::client_session <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ API documentation. + To learn more, see `mongocxx::client_session <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ in the API documentation. -The following code shows how to use the core API to perform a transaction. +The following code shows how to use the core API to perform a transaction that inserts documents into collections in the ``sample_mflix`` database. When run, the code performs the following actions: 1. Starts a session from the client using the ``start_session()`` method. #. Creates an option object to set the write preference for the transaction operations. #. Calls the ``start_transaction()`` method to start a transaction, passing in the option object as an argument. -#. Attempts to insert documents into collections in the ``sample_mflix`` database. +#. Attempts operations to insert documents into collections in the ``sample_mflix`` database. If an operation encounters an error, the transaction is aborted and then retried if the error has the label ``TransientTransactionError``. #. Calls the ``commit_transaction()`` method to commit the active transaction. If the commit encounters an error with the label ``UnknownTransactionCommitResult``, the commit is retried. From c317a97c6b1b1197299d971acdd06004d4aae3dd Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Thu, 21 Nov 2024 12:01:28 -0500 Subject: [PATCH 21/32] (DOCSP-45012) Edits. --- source/includes/write/transactions.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/includes/write/transactions.cpp b/source/includes/write/transactions.cpp index b8ee6006..4d7be2b6 100644 --- a/source/includes/write/transactions.cpp +++ b/source/includes/write/transactions.cpp @@ -137,8 +137,5 @@ int main() { } // end-core-api } - - - } From 790110f23d9883e15d47b317b5aa659247ae2039 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Thu, 21 Nov 2024 12:09:41 -0500 Subject: [PATCH 22/32] (DOCSP-45012) Fix links.g --- source/write/transactions.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/write/transactions.txt b/source/write/transactions.txt index a4f46708..85e97f23 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -97,8 +97,8 @@ When run, the code performs the following actions: Core API ~~~~~~~~ -Use the core API for more manual control of the transaction lifecycle. The core API doesn't incorporate error handling logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult``, -and instead provides the flexibility to incorporate custom error handling for these errors. To learn more about how to handle ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` errors, +Use the core API for more manual control of the transaction lifecycle. The core API doesn't incorporate error handling logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` errors, +and instead provides the flexibility to incorporate custom error handling. To learn more about these errors, see the :manual:`Transaction Error Handling ` section in the {+mdb-server+} manual. The core API requires explicit calls to start, commit, and abort the transaction using methods provided by the ``mongocxx::client_session`` interface. @@ -189,11 +189,11 @@ To learn more about any of the types or methods discussed in this guide, see the following API Documentation: - `mongocxx::client <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ -- `mongocxx::client_session <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html>`__ +- `mongocxx::client_session <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1transaction.html>`__ - `mongocxx::options::transaction <{+api+}/classmongocxx_1_1options_1_1transaction.html>`__ - `start_session() <{+api+}/classmongocxx_1_1v__noabi_1_1client.html#a03535128dbe5be973a08764b7741f24e>`__ - `with_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#a3dcdf91bf72e69bf7e63a7c8ad859b93>`__ -- `start_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#a84ea5613813e6efbe065e3f39e1f972b>`__ +- `start_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#a9cc1c32d80a6cb1b0b21001d7990111b>`__ - `commit_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#ad2d1a8f7c77542db6ec7629d162761ff>`__ - `abort_transaction() <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html#aabb8247a655741af6fe0f78bef8116e1>`__ - `insert_one() <{+api+}/classmongocxx_1_1v__noabi_1_1collection.html#a839bedb5505e5ce75cbf384e2e2457bd>`__ \ No newline at end of file From 665e5c0f1b98373e08c2310c3196cde6fc8eec00 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Thu, 21 Nov 2024 13:22:30 -0500 Subject: [PATCH 23/32] (DOCSP-45012) Edits + vale fix. --- source/write/transactions.txt | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/source/write/transactions.txt b/source/write/transactions.txt index 85e97f23..ac3798d1 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -55,29 +55,20 @@ Transaction APIs The {+driver-long+} provides a callback API and a core API to manage the transaction lifestyle. Before you begin a transaction, you must call the ``start_session()`` method to instantiate a ``mongocxx::client_session``. -Then, you can choose one of the following transaction APIs to perform a transaction: +Then, you can use one of the transaction APIs described in the following sections to perform a transaction: -- Callback API -- Core API - -To learn more about transaction APIs, see the :manual:`Drivers API ` page in the {+mdb-server+} manual. +- :ref:`Callback API ` +- :ref:`Core API ` .. _cpp-callback-api: Callback API ~~~~~~~~~~~~ -Use the callback API to start a transaction, execute specified operations, and commit the transaction with -incorporated retry logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` errors. +Use the callback API to start, execute, and commit a transaction with incorporated retry logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` errors. To implement this API, call the ``with_transaction()`` method on your ``mongocxx::client_session`` and pass in a callback specifying the sequence of operations you want to run in your transaction. -.. The ``with_transaction()`` method performs the following tasks: - -.. - Starts a new transaction on this client session -.. - Runs the provided callback, automatically incorporating retry logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` -.. - Commits the transaction - The following code shows how to use the callback API to perform a transaction that inserts documents into collections in the ``sample_mflix`` database. When run, the code performs the following actions: @@ -156,7 +147,7 @@ When run, the code performs the following actions: #. Attempts operations to insert documents into collections in the ``sample_mflix`` database. If an operation encounters an error, the transaction is aborted and then retried if the error has the label ``TransientTransactionError``. -#. Calls the ``commit_transaction()`` method to commit the active transaction. If the commit encounters an error with the label ``UnknownTransactionCommitResult``, the commit is retried. +#. Commits the active transaction using the ``commit_transaction()`` method. If the commit encounters an error with the label ``UnknownTransactionCommitResult``, the commit is retried. .. literalinclude:: /includes/write/transactions.cpp :language: cpp From 2931dc770b992d7c43f49fdfcab56bdbd189d66d Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Thu, 21 Nov 2024 13:22:43 -0500 Subject: [PATCH 24/32] (DOCSP-45012) Vale error fix. --- .github/workflows/vale-tdbx.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/vale-tdbx.yml b/.github/workflows/vale-tdbx.yml index ca2a7348..020bf61d 100644 --- a/.github/workflows/vale-tdbx.yml +++ b/.github/workflows/vale-tdbx.yml @@ -12,6 +12,9 @@ jobs: - name: checkout uses: actions/checkout@v4 + - name: Install docutils + run: sudo apt-get install -y docutils + - id: files uses: masesgroup/retrieve-changed-files@v2 with: From 151276440577b8dd7c306b932d9390af7b8d14ec Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Thu, 21 Nov 2024 14:25:21 -0500 Subject: [PATCH 25/32] (DOCSP-45012) Edit. --- source/write/transactions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/write/transactions.txt b/source/write/transactions.txt index ac3798d1..b84ff36c 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -55,7 +55,7 @@ Transaction APIs The {+driver-long+} provides a callback API and a core API to manage the transaction lifestyle. Before you begin a transaction, you must call the ``start_session()`` method to instantiate a ``mongocxx::client_session``. -Then, you can use one of the transaction APIs described in the following sections to perform a transaction: +Then, you can use either of the following APIs to perform a transaction: - :ref:`Callback API ` - :ref:`Core API ` From 7f33c5469623be57d37f99ee77ea563b0588d7eb Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Thu, 21 Nov 2024 16:07:12 -0500 Subject: [PATCH 26/32] (DOCSP-45012) Add refs. --- source/write/transactions.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/write/transactions.txt b/source/write/transactions.txt index b84ff36c..57464181 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -50,6 +50,8 @@ instantiating a new client each time. Each ``mongoxcc::client`` instance and all of its child instances, including ``mongocxx::client_session``, should be used by a single thread at a time. To learn more, see the :ref:`Thread and Fork Safety ` page. +.. _cpp-transaction-apis: + Transaction APIs ---------------- @@ -155,6 +157,8 @@ When run, the code performs the following actions: :start-after: start-core-api :end-before: end-core-api +.. _cpp-transactions-addtl-info: + Additional Information ---------------------- From 17424ef13a818771959d1064a01774ec6ebef314 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Fri, 22 Nov 2024 12:37:49 -0500 Subject: [PATCH 27/32] (DOCSP-45012) Fix links. --- source/write/transactions.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/write/transactions.txt b/source/write/transactions.txt index 57464181..a1861cdf 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -106,8 +106,8 @@ The following table describes these methods: * - ``start_transaction()`` - | Starts a new transaction on the current client session. Accepts an optional ``mongocxx::options::transaction`` - instance as an argument to set options. For a full list of options, see the `mongocxx::options::transaction <{+api+}/mongocxx-3.4.1/classmongocxx_1_1options_1_1transaction.html>`__ - API documentation. + instance as an argument to set options. For a full list of options, see `mongocxx::options::transaction <{+api+}/classmongocxx_1_1options_1_1transaction.html>`__ + in the API documentation. | | Raises an exception if the options are misconfigured, if there are network or other transient failures, or if there are other errors such as a session with a transaction already in progress. If an error is returned with the ``TransientTransactionError`` label, From 975484441385cc2e58574db8afa31c2e84af3244 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Fri, 22 Nov 2024 16:38:49 -0500 Subject: [PATCH 28/32] (DOCSP-45012) @mayaraman19 Review feedback. --- source/includes/write/transactions.cpp | 28 +++++++++------- source/write/transactions.txt | 45 +++++++++++++++----------- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/source/includes/write/transactions.cpp b/source/includes/write/transactions.cpp index 4d7be2b6..be1d4285 100644 --- a/source/includes/write/transactions.cpp +++ b/source/includes/write/transactions.cpp @@ -28,10 +28,10 @@ int main() { 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", "Rhaenyra Targaryen"), kvp("text", "Dracarys."))); + comments_collection.insert_one(*session, make_document(kvp("name", "Anjali Pateln"), kvp("text", "This is my new favorite movie."))); }; - // Define an options instance to set the majority write concern for the transaction operations explicitly + // 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); @@ -57,18 +57,21 @@ int main() { mongocxx::instance instance{}; mongocxx::client client(mongocxx::uri{""}); - // Incorporate TransientTransactionError retry logic + // Runs the txn_func and retries if TransientTransactionError occurs using transaction_func = std::function; - auto run_with_retry = [](transaction_func txn_func, 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; + 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; + std::cout << "TransientTransactionError, retrying transaction ..." + << std::endl; continue; } else { throw oe; @@ -77,7 +80,7 @@ int main() { } }; - // Incorporate UnknownTransactionCommitResult retry logic + // Commits the active transaction and retries commit if UnknownTransactionCommitResult occurs auto commit_with_retry = [](mongocxx::client_session& session) { while (true) { try { @@ -87,7 +90,8 @@ int main() { } catch (const mongocxx::operation_exception& oe) { // Can retry commit if (oe.has_error_label("UnknownTransactionCommitResult")) { - std::cout << "UnknownTransactionCommitResult, retrying commit operation ..." << std::endl; + std::cout << "UnknownTransactionCommitResult, retrying commit ..." + << std::endl; continue; } else { std::cout << "Error during commit ..." << std::endl; @@ -97,7 +101,7 @@ int main() { } }; - auto run_transaction = [&](mongocxx::client_session& session) { + auto txn_func = [&](mongocxx::client_session& session) { auto& client = session.client(); // Define database and collection variables @@ -105,7 +109,7 @@ int main() { auto movies_collection = db["movies"]; auto comments_collection = db["comments"]; - // Define an options instance to set the majority write concern for the transaction operations explicitly + // 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); @@ -116,7 +120,7 @@ int main() { // 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", "Rhaenyra Targaryen"), kvp("text", "Dracarys"))); + 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(); @@ -130,7 +134,7 @@ int main() { auto session = client.start_session(); try { - run_transaction_with_retry(run_transaction, session); + run_with_retry(txn_func, session); } catch (const mongocxx::operation_exception& oe) { // Do something with error throw oe; diff --git a/source/write/transactions.txt b/source/write/transactions.txt index a1861cdf..a7720b4d 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -47,7 +47,7 @@ instantiating a new client each time. .. important:: Instances of ``mongocxx::client`` are not thread-safe. - Each ``mongoxcc::client`` instance and all of its child instances, including ``mongocxx::client_session``, should be used by a single thread at a time. + Each ``mongoxcc::client`` instance and its child instances, including ``mongocxx::client_session``, should be used by a single thread at a time. To learn more, see the :ref:`Thread and Fork Safety ` page. .. _cpp-transaction-apis: @@ -59,25 +59,33 @@ The {+driver-long+} provides a callback API and a core API to manage the transac Before you begin a transaction, you must call the ``start_session()`` method to instantiate a ``mongocxx::client_session``. Then, you can use either of the following APIs to perform a transaction: -- :ref:`Callback API ` -- :ref:`Core API ` +- :ref:`Callback API `: High-level API that manages the life cycle of the transaction and automatically incorporates error handling logic. +- :ref:`Core API `: Low-level API that allows you to manually manage the life cycle of the transaction and implement custom error handling logic. + +.. tip:: + + To learn more about error handling, see the :manual:`Transaction Error Handling ` section in the {+mdb-server+} manual. .. _cpp-callback-api: Callback API ~~~~~~~~~~~~ -Use the callback API to start, execute, and commit a transaction with incorporated retry logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` errors. +Use the callback API to allow the {+driver-long+} to manage the life cycle of your transaction. To implement this API, call the ``with_transaction()`` method on your ``mongocxx::client_session`` and pass in a -callback specifying the sequence of operations you want to run in your transaction. +callback function specifying the sequence of operations you want to run in your transaction. The ``with_transaction()`` method starts a transaction, executes the callback function, and +either commits your transaction or ends it if it encounters an error. +If an error has the label ``TransientTransactionError`` and ``UnknownTransactionCommitResult``, the ``with_transaction()`` method automatically incorporates retry logic. -The following code shows how to use the callback API to perform a transaction that inserts documents into collections in the ``sample_mflix`` database. -When run, the code performs the following actions: +The following code shows how to use the callback API to perform a transaction that inserts documents into the ``movies`` and ``comments`` collections in the ``sample_mflix`` database. +This code performs the following actions: -1. Starts a session from the client using the ``start_session()`` method -#. Defines a callback function that specifies the operations to perform during the transaction -#. Creates an option object to set the write preference for the transaction operations -#. Calls the ``with_transactions()`` method to manage the transaction, passing the callback and option object as arguments +1. Starts a session from the client using the ``start_session()`` method. +#. Defines a callback function that specifies the operations to perform during the transaction. +#. Creates an option object to set the write concern for the transaction operations. + To learn more about read and write semantics, see the :manual:`Read Concern/Write Concern/Read Preference ` + section in the {+mdb-server+} manual. +#. Calls the ``with_transaction()`` method to manage the transaction, passing the callback function and option object as arguments. .. literalinclude:: /includes/write/transactions.cpp :language: cpp @@ -90,9 +98,8 @@ When run, the code performs the following actions: Core API ~~~~~~~~ -Use the core API for more manual control of the transaction lifecycle. The core API doesn't incorporate error handling logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` errors, -and instead provides the flexibility to incorporate custom error handling. To learn more about these errors, -see the :manual:`Transaction Error Handling ` section in the {+mdb-server+} manual. +Use the core API to manually manage the life cycle of your transaction. The core API doesn't incorporate error handling logic +for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` errors, and instead provides the flexibility to implement custom error handling logic. The core API requires explicit calls to start, commit, and abort the transaction using methods provided by the ``mongocxx::client_session`` interface. The following table describes these methods: @@ -126,7 +133,7 @@ The following table describes these methods: | To learn more about this method, see the :manual:`commitTransaction() ` guide in the {+mdb-server+} manual. - * - ``abort_transcaction()`` + * - ``abort_transaction()`` - | Ends the active transaction on the current client session. | | Raises an exception if the options are misconfigured or if there are other errors such as @@ -140,11 +147,13 @@ The following table describes these methods: The ``mongocxx::client_session`` class also provides methods to retrieve and modify session properties. To learn more, see `mongocxx::client_session <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ in the API documentation. -The following code shows how to use the core API to perform a transaction that inserts documents into collections in the ``sample_mflix`` database. -When run, the code performs the following actions: +The following code shows how to use the core API to perform a transaction that inserts documents into the ``movies`` and ``comments`` collections in the ``sample_mflix`` database. +This code performs the following actions: 1. Starts a session from the client using the ``start_session()`` method. -#. Creates an option object to set the write preference for the transaction operations. +#. Creates an option object to set the write concern for the transaction operations. + To learn more about read and write semantics, see the :manual:`Read Concern/Write Concern/Read Preference ` + section in the {+mdb-server+} manual. #. Calls the ``start_transaction()`` method to start a transaction, passing in the option object as an argument. #. Attempts operations to insert documents into collections in the ``sample_mflix`` database. If an operation encounters an error, the transaction is aborted and From 1c11e70f4dda7c9df8f64d25e4f8fed67aecc0e8 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Fri, 22 Nov 2024 16:51:50 -0500 Subject: [PATCH 29/32] (DOCSP-45012) Clean up. --- source/includes/write/transactions.cpp | 14 +++++++++----- source/write/transactions.txt | 8 ++++---- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/source/includes/write/transactions.cpp b/source/includes/write/transactions.cpp index be1d4285..d15fe7ad 100644 --- a/source/includes/write/transactions.cpp +++ b/source/includes/write/transactions.cpp @@ -70,7 +70,7 @@ int main() { << std::endl; // If transient error, retry the whole transaction. if (oe.has_error_label("TransientTransactionError")) { - std::cout << "TransientTransactionError, retrying transaction ..." + std::cout << "TransientTransactionError, retrying transaction..." << std::endl; continue; } else { @@ -85,20 +85,23 @@ int main() { while (true) { try { session.commit_transaction(); // Uses write concern set at transaction start. - std::cout << "Transaction committed." << std::endl; + 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::cout << "UnknownTransactionCommitResult, retrying commit..." << std::endl; continue; } else { - std::cout << "Error during commit ..." << std::endl; + std::cout << "Error during commit..." + << std::endl; throw oe; } } } + }; auto txn_func = [&](mongocxx::client_session& session) { @@ -122,7 +125,8 @@ int main() { 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; + std::cout << "Caught exception during transaction, aborting." + << std::endl; session.abort_transaction(); throw oe; } diff --git a/source/write/transactions.txt b/source/write/transactions.txt index a7720b4d..550a3486 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -73,8 +73,8 @@ Callback API Use the callback API to allow the {+driver-long+} to manage the life cycle of your transaction. To implement this API, call the ``with_transaction()`` method on your ``mongocxx::client_session`` and pass in a -callback function specifying the sequence of operations you want to run in your transaction. The ``with_transaction()`` method starts a transaction, executes the callback function, and -either commits your transaction or ends it if it encounters an error. +callback function specifying the sequence of operations you want to run. The ``with_transaction()`` method starts a transaction, executes the callback function, and +either commits your transaction or ends it and incorporates error handling logic. If an error has the label ``TransientTransactionError`` and ``UnknownTransactionCommitResult``, the ``with_transaction()`` method automatically incorporates retry logic. The following code shows how to use the callback API to perform a transaction that inserts documents into the ``movies`` and ``comments`` collections in the ``sample_mflix`` database. @@ -113,7 +113,7 @@ The following table describes these methods: * - ``start_transaction()`` - | Starts a new transaction on the current client session. Accepts an optional ``mongocxx::options::transaction`` - instance as an argument to set options. For a full list of options, see `mongocxx::options::transaction <{+api+}/classmongocxx_1_1options_1_1transaction.html>`__ + instance as an argument to set options. For a full list of options, see `mongocxx::options::transaction <{+api+}/classmongocxx_1_1v__noabi_1_1options_1_1transaction.html>`__ in the API documentation. | | Raises an exception if the options are misconfigured, if there are network or other transient failures, or if there @@ -145,7 +145,7 @@ The following table describes these methods: .. tip:: The ``mongocxx::client_session`` class also provides methods to retrieve and modify session properties. - To learn more, see `mongocxx::client_session <{+api+}/classmongocxx_1_1v__noabi_1_1client.html>`__ in the API documentation. + To learn more, see `mongocxx::client_session <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html>`__ in the API documentation. The following code shows how to use the core API to perform a transaction that inserts documents into the ``movies`` and ``comments`` collections in the ``sample_mflix`` database. This code performs the following actions: From b66894878df73d4f908240abe13a6d769faec345 Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Fri, 22 Nov 2024 17:01:13 -0500 Subject: [PATCH 30/32] (DOCSP-45012) Clean up. --- source/includes/write/transactions.cpp | 6 ++++-- source/write/transactions.txt | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/source/includes/write/transactions.cpp b/source/includes/write/transactions.cpp index d15fe7ad..ef17065a 100644 --- a/source/includes/write/transactions.cpp +++ b/source/includes/write/transactions.cpp @@ -28,7 +28,8 @@ int main() { 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 Pateln"), kvp("text", "This is my new favorite movie."))); + 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 @@ -123,7 +124,8 @@ int main() { // 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."))); + 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; diff --git a/source/write/transactions.txt b/source/write/transactions.txt index 550a3486..fe51c0fa 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -48,7 +48,7 @@ instantiating a new client each time. Instances of ``mongocxx::client`` are not thread-safe. Each ``mongoxcc::client`` instance and its child instances, including ``mongocxx::client_session``, should be used by a single thread at a time. - To learn more, see the :ref:`Thread and Fork Safety ` page. + To learn more, see the :ref:`Thread and Fork Safety ` guide. .. _cpp-transaction-apis: @@ -73,7 +73,9 @@ Callback API Use the callback API to allow the {+driver-long+} to manage the life cycle of your transaction. To implement this API, call the ``with_transaction()`` method on your ``mongocxx::client_session`` and pass in a -callback function specifying the sequence of operations you want to run. The ``with_transaction()`` method starts a transaction, executes the callback function, and +callback function specifying the sequence of operations you want to run. + +The ``with_transaction()`` method starts a transaction, executes the callback function, and either commits your transaction or ends it and incorporates error handling logic. If an error has the label ``TransientTransactionError`` and ``UnknownTransactionCommitResult``, the ``with_transaction()`` method automatically incorporates retry logic. From 02d60111205e79eac8d8fad183c20539286b4eca Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Mon, 25 Nov 2024 13:16:42 -0500 Subject: [PATCH 31/32] (DOCSP-45012) @mayaraman19 Final round of review edits. --- source/write/transactions.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/write/transactions.txt b/source/write/transactions.txt index fe51c0fa..523bd5ff 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -60,7 +60,7 @@ Before you begin a transaction, you must call the ``start_session()`` method to Then, you can use either of the following APIs to perform a transaction: - :ref:`Callback API `: High-level API that manages the life cycle of the transaction and automatically incorporates error handling logic. -- :ref:`Core API `: Low-level API that allows you to manually manage the life cycle of the transaction and implement custom error handling logic. +- :ref:`Core API `: Low-level API that allows you to manage the life cycle of the transaction and implement custom error handling logic. .. tip:: @@ -100,11 +100,12 @@ This code performs the following actions: Core API ~~~~~~~~ -Use the core API to manually manage the life cycle of your transaction. The core API doesn't incorporate error handling logic +Use the core API to manage the life cycle of your transaction. + +The core API requires explicit calls to start, commit, and abort the transaction using methods provided by the ``mongocxx::client_session`` interface. The core API doesn't incorporate error handling logic for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` errors, and instead provides the flexibility to implement custom error handling logic. -The core API requires explicit calls to start, commit, and abort the transaction using methods provided by the ``mongocxx::client_session`` interface. -The following table describes these methods: +The following table describes the core API methods provided by the ``mongocxx::client_session`` interface: .. list-table:: :widths: 25 75 From 7a3fc409b6d3f18ef9aa3527dc2c43df719a699d Mon Sep 17 00:00:00 2001 From: Elyse Foreman Date: Mon, 25 Nov 2024 15:57:24 -0500 Subject: [PATCH 32/32] (DOCSP-45012) Edits. --- source/write/transactions.txt | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/source/write/transactions.txt b/source/write/transactions.txt index 523bd5ff..6435f2bd 100644 --- a/source/write/transactions.txt +++ b/source/write/transactions.txt @@ -73,18 +73,16 @@ Callback API Use the callback API to allow the {+driver-long+} to manage the life cycle of your transaction. To implement this API, call the ``with_transaction()`` method on your ``mongocxx::client_session`` and pass in a -callback function specifying the sequence of operations you want to run. +callback function specifying the sequence of operations you want to run. The ``with_transaction()`` method starts a transaction, executes the callback function, and +either commits your transaction or ends the transaction if it encounters an error. If your transaction encounters a ``TransientTransactionError`` or ``UnknownTransactionCommitResult`` error, the +``with_transaction()`` method reruns the transaction. -The ``with_transaction()`` method starts a transaction, executes the callback function, and -either commits your transaction or ends it and incorporates error handling logic. -If an error has the label ``TransientTransactionError`` and ``UnknownTransactionCommitResult``, the ``with_transaction()`` method automatically incorporates retry logic. - -The following code shows how to use the callback API to perform a transaction that inserts documents into the ``movies`` and ``comments`` collections in the ``sample_mflix`` database. +The following code uses the callback API to perform a transaction that inserts documents into the ``movies`` and ``comments`` collections in the ``sample_mflix`` database. This code performs the following actions: 1. Starts a session from the client using the ``start_session()`` method. #. Defines a callback function that specifies the operations to perform during the transaction. -#. Creates an option object to set the write concern for the transaction operations. +#. Creates an option object to prepare to set the write concern for the transaction operations. To learn more about read and write semantics, see the :manual:`Read Concern/Write Concern/Read Preference ` section in the {+mdb-server+} manual. #. Calls the ``with_transaction()`` method to manage the transaction, passing the callback function and option object as arguments. @@ -100,10 +98,9 @@ This code performs the following actions: Core API ~~~~~~~~ -Use the core API to manage the life cycle of your transaction. - -The core API requires explicit calls to start, commit, and abort the transaction using methods provided by the ``mongocxx::client_session`` interface. The core API doesn't incorporate error handling logic -for ``TransientTransactionError`` and ``UnknownTransactionCommitResult`` errors, and instead provides the flexibility to implement custom error handling logic. +Use the core API to manage the life cycle of your transaction. To implement this API, you must make explicit calls to methods in the ``mongocxx::client_session`` interface +to start a transaction, commit an active transaction, and end a transaction if an error occurs. The core API doesn't automatically incorporate error handling logic, +and instead allows you to implement custom handling logic for errors including ``TransientTransactionError`` and ``UnknownTransactionCommitResult``. The following table describes the core API methods provided by the ``mongocxx::client_session`` interface: @@ -150,17 +147,18 @@ The following table describes the core API methods provided by the ``mongocxx::c The ``mongocxx::client_session`` class also provides methods to retrieve and modify session properties. To learn more, see `mongocxx::client_session <{+api+}/classmongocxx_1_1v__noabi_1_1client__session.html>`__ in the API documentation. -The following code shows how to use the core API to perform a transaction that inserts documents into the ``movies`` and ``comments`` collections in the ``sample_mflix`` database. +The following code uses the core API to perform a transaction that inserts documents into the ``movies`` and ``comments`` collections in the ``sample_mflix`` database. This code performs the following actions: 1. Starts a session from the client using the ``start_session()`` method. -#. Creates an option object to set the write concern for the transaction operations. +#. Creates an option object to prepare to set the write concern for the transaction operations. To learn more about read and write semantics, see the :manual:`Read Concern/Write Concern/Read Preference ` section in the {+mdb-server+} manual. #. Calls the ``start_transaction()`` method to start a transaction, passing in the option object as an argument. -#. Attempts operations to insert documents into collections in the ``sample_mflix`` database. - If an operation encounters an error, the transaction is aborted and - then retried if the error has the label ``TransientTransactionError``. +#. Runs operations to insert documents into collections in the ``sample_mflix`` database, passing the active + session to each operation. + If an operation encounters an error, the whole transaction is aborted. If the error has the label ``TransientTransactionError``, + the transaction is retried. #. Commits the active transaction using the ``commit_transaction()`` method. If the commit encounters an error with the label ``UnknownTransactionCommitResult``, the commit is retried. .. literalinclude:: /includes/write/transactions.cpp