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>`_