From 17a3d5dece978590409692155283d4c1f0d0b264 Mon Sep 17 00:00:00 2001 From: Stephanie <52582720+stephmarie17@users.noreply.github.com> Date: Fri, 27 Sep 2024 11:10:24 -0700 Subject: [PATCH] DOCSP-41763 Add transaction page (#47) Add transactions page and code example (cherry picked from commit 8e97db7dbd0c9d5a11760a3f69db1630911af9a4) --- source/includes/write/transaction.kt | 57 ++++++++++ source/write-operations.txt | 1 + source/write/transactions.txt | 164 +++++++++++++++++++++++++++ 3 files changed, 222 insertions(+) create mode 100644 source/includes/write/transaction.kt create mode 100644 source/write/transactions.txt diff --git a/source/includes/write/transaction.kt b/source/includes/write/transaction.kt new file mode 100644 index 0000000..e708b96 --- /dev/null +++ b/source/includes/write/transaction.kt @@ -0,0 +1,57 @@ +import com.mongodb.kotlin.client.ClientSession +import com.mongodb.kotlin.client.MongoClient +import org.bson.Document +import com.mongodb.ReadConcern +import com.mongodb.TransactionOptions +import com.mongodb.WriteConcern + +// start-data-class +data class Restaurant(val name: String, val cuisine: String) +// end-data-class + +fun main() { +// start-transaction + // Creates a new MongoClient to manage your connection + val client = MongoClient.create("<connection string>") + + // Gets the database and collection + val database = client.getDatabase("sample_restaurants") + val collection = database.getCollection<Restaurant>("restaurants") + + // Inserts restaurants into the collection + fun insertRestaurantsInTransaction(session: ClientSession) { + + // Inserts restaurants within the transaction + collection.insertOne( + session, + Restaurant("Kotlin Sync Pizza", "Pizza") + ) + collection.insertOne( + session, + Restaurant("Kotlin Sync Burger", "Burger") + ) + } + + // Starts a client session + client.startSession().use { session -> + try { + // Sets transaction options + val txnOptions = TransactionOptions.builder() + .readConcern(ReadConcern.LOCAL) + .writeConcern(WriteConcern.MAJORITY) + .build() + + // Uses the withTransaction method to start a transaction and run the given function + session.withTransaction({ + insertRestaurantsInTransaction(session) + println("Transaction succeeded") + }, txnOptions) + } catch (e: Exception) { + println("Transaction failed: ${e.message}") + } + } + + // Closes the MongoClient + client.close() +// end-transaction +} \ No newline at end of file diff --git a/source/write-operations.txt b/source/write-operations.txt index 7760534..19b7e69 100644 --- a/source/write-operations.txt +++ b/source/write-operations.txt @@ -27,6 +27,7 @@ Write Data to MongoDB /write/replace /write/delete /write/bulk-write + /write/transactions .. /write/gridfs diff --git a/source/write/transactions.txt b/source/write/transactions.txt new file mode 100644 index 0000000..f210f20 --- /dev/null +++ b/source/write/transactions.txt @@ -0,0 +1,164 @@ +.. _kotlin-sync-write-transactions: + +============ +Transactions +============ + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: ACID, write, consistency, code example + +Overview +-------- + +In this guide, you can learn how to use the {+driver-short+} to perform +**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 +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 and allow you to run 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 +``MongoClient`` instance as a ``ClientSession`` type. We recommend that you reuse +your ``MongoClient`` for multiple sessions and transactions instead of +creating a new client each time. + +.. warning:: + + Use a ``ClientSession`` only with the ``MongoClient`` (or associated + ``MongoDatabase`` or ``MongoCollection``) that created it. Using a + ``ClientSession`` with a different ``MongoClient`` results in operation + errors. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``sample_restaurants.restaurants`` collection +from the :atlas:`Atlas sample datasets </sample-data>`. To learn how to create a +free MongoDB Atlas cluster and load the sample datasets, see the +:atlas:`Get Started with Atlas </getting-started>` guide. + +The documents in this collection are modeled by the following {+language+} data class: + +.. literalinclude:: /includes/write/transaction.kt + :start-after: start-data-class + :end-before: end-data-class + :language: kotlin + :copyable: + :dedent: + +Methods +------- + +Create a ``ClientSession`` by using the ``startSession()`` method on your ``MongoClient`` +instance. You can then modify the session state by using the methods provided by +the ``ClientSession``. The following table describes the methods you can use to +manage your transaction: + +.. 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 + </reference/method/Session.startTransaction/>` in the Server manual. + | + | **Parameter**: ``TransactionOptions`` + + * - ``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 + </reference/method/Session.abortTransaction/>` in the Server manual. + | + + * - ``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 + </reference/method/Session.commitTransaction/>` in the Server manual. + + * - ``withTransaction()`` + - | Starts a transaction on this session and runs the given function within + a transaction. + | + | **Parameters**: transaction body function, ``TransactionOptions`` + +Example +------- + +The following example demonstrates how to create a session, create a +transaction, and insert documents into a collection in one transaction +through the following steps: + +1. Create a session from the client by using the ``startSession()`` method. +#. Define the ``insertRestaurantsInTransaction()`` method to insert multiple + documents into the ``restaurants`` collection. +#. Use the ``withTransaction()`` method to start a transaction. The ``withTransaction()`` + method runs the insert operations and commits the transaction. If any + operation results in errors, ``withTransaction()`` cancels the transaction. +#. Close the connection to the server by using the ``MongoClient.close()`` method. + +.. literalinclude:: /includes/write/transaction.kt + :start-after: start-transaction + :end-before: end-transaction + :language: kotlin + :copyable: + :dedent: + +If you require more control over your transactions, you can use the ``startTransaction()`` +method. You can use this method with the ``commitTransaction()`` and ``abortTransaction()`` +methods described in the preceding section to manually manage the transaction lifecycle. + +Additional Information +---------------------- + +To learn more about the concepts mentioned in this guide, see the following pages in +the Server manual: + +- :manual:`Transactions </core/transactions/>` +- :manual:`Server Sessions </reference/server-sessions>` +- :manual:`Read Isolation, Consistency, and Recency </core/read-isolation-consistency-recency/#causal-consistency>` + +To learn more about ACID compliance, see the :website:`What are ACID +Properties in Database Management Systems? </basics/acid-transactions>` +article on the MongoDB website. + +.. _kotlin-sync-api-docs-transaction: + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the types or methods discussed in this +guide, see the following API documentation: + +- `ClientSession <{+api+}/com.mongodb.kotlin.client/-client-session/index.html>`_ +- `abortTransaction() <{+api+}/com.mongodb.kotlin.client/-client-session/abort-transaction.html>`_ +- `commitTransaction() <{+api+}/com.mongodb.kotlin.client/-client-session/commit-transaction.html>`_ +- `startTransaction() <{+api+}/com.mongodb.kotlin.client/-client-session/start-transaction.html>`_ +- `withTransaction() <{+api+}/com.mongodb.kotlin.client/-client-session/with-transaction.html>`_