> For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

# Transactions

## Overview

In this guide, you can learn how to use the Node.js driver to perform **transactions**. Transactions allow you to run a series of operations that do not change any data until the entire transaction is committed. If any operation in the transaction fails, the driver ends the transaction and discards all data changes before they ever become visible. This feature is called **atomicity**.

Since all write operations on a single document in MongoDB are atomic, you might want to use transactions to make an atomic change that modifies multiple documents. This situation requires a multi-document transaction. Multi-document transactions are **ACID compliant** because MongoDB guarantees that the data involved in your transaction operations remains consistent, even if the driver encounters unexpected errors.

To learn more about ACID compliance and transactions, see our [article on ACID transactions.](https://www.mongodb.com/basics/acid-transactions?tck=docs)

**Note:**

To execute a multi-document transaction, you must be connected to a deployment running MongoDB Server version 4.0 or later.

For a detailed list of limitations, see the [Transactions and Operations](https://www.mongodb.com/docs/manual/core/transactions/#transactions-and-operations) section in the Server manual.

Learn more about how to use the driver to perform multi-document transactions in the following sections of this guide:

- [Transaction APIs](https://www.mongodb.com/docs/drivers/node/current/crud/transactions.md#std-label-nodejs-transaction-apis)

- [Transaction Options](https://www.mongodb.com/docs/drivers/node/current/crud/transactions.md#std-label-nodejs-transaction-settings)

- [Transaction Errors](https://www.mongodb.com/docs/drivers/node/current/crud/transactions.md#std-label-nodejs-transaction-errors)

### Causal Consistency

MongoDB enables **causal consistency** in certain client sessions. The causal consistency model guarantees that in a distributed system, operations within a session run in a causal order. Clients observe results that are consistent with the causal relationships, or the dependencies between operations. For example, if you perform a series of operations where one operation logically depends on the result of another, any subsequent reads reflect the dependent relationship.

To guarantee causal consistency, client sessions must fulfill the following requirements:

- When starting a session, the driver must enable the causal consistency option. This option is enabled by default.

- Operations must run in a single session on a single thread. Otherwise, the sessions or threads must communicate the operation time and cluster time values to each other. To view an example of two sessions that communicate these values, see the [Causal Consistency examples](https://www.mongodb.com/docs/manual/core/read-isolation-consistency-recency/#examples) in the MongoDB Server manual.

- You must use a `majority` read concern.

- You must use a `majority` write concern. This is the default write concern value.

The following table describes the guarantees that causally consistent sessions provide:

| Guarantee | Description |
| --- | --- |
| Read your writes | Read operations reflect the results of preceding write operations. |
| Monotonic reads | Read operations do not return results that reflect an earlier data state than a preceding read operation. |
| Monotonic writes | If a write operation must precede other write operations, the server runs this write operation first. For example, if you call `insertOne()` to insert a document, then call `updateOne()` to modify the inserted document, the server runs the insert operation first. |
| Writes follow reads | If a write operation must follow other read operations, the server runs the read operations first. For example, if you call `findOne()` to retrieve a document, then call `deleteOne()` to delete the retrieved document, the server runs the find operation first. |

**Tip:**

To learn more about the concepts mentioned in this section, see the following MongoDB Server manual entries:

- [Causal Consistency](https://www.mongodb.com/docs/manual/core/read-isolation-consistency-recency/#causal-consistency)

- [Causal Consistency and Read and Write Concerns](https://www.mongodb.com/docs/manual/core/causal-consistency-read-write-concerns/)

## Transaction APIs

The driver provides two APIs for performing transactions, the **Core
API** and the **Convenient Transaction API**.

The [Core API](https://www.mongodb.com/docs/drivers/node/current/crud/transactions.md#std-label-node-txn-core-api) is a framework that enables you to create, commit, and end transactions. When using this API, you must explicitly perform the following actions:

- Create, commit, and end the transaction.

- Create and end the session in which you run the transaction.

- Implement error-handling logic.

The [Convenient Transaction API](https://www.mongodb.com/docs/drivers/node/current/crud/transactions.md#std-label-node-txn-convenient-api) is a framework that enables you to perform transactions without being responsible for committing or ending them. This API automatically incorporates error-handling logic to retry operations when the server raises certain error types. To learn more about this behavior, see the [Transaction Errors](https://www.mongodb.com/docs/drivers/node/current/crud/transactions.md#std-label-nodejs-transaction-errors) section of this guide.

**Important:**

When you connect to MongoDB Server version 4.2 or earlier, you can perform write operations in a transaction only on collections that already exist. When you connect to MongoDB Server version 4.4 and later, the server automatically creates collections as necessary when you perform write operations in a transaction. To learn more about this behavior, see [Create Collections and Indexes in a Transaction](https://www.mongodb.com/docs/manual/core/transactions/#create-collections-and-indexes-in-a-transaction) in the Server manual.

### Core API

The Core API provides the following methods to implement transactions:

- [startSession()](https://mongodb.github.io/node-mongodb-native/7.7/classes/MongoClient.html#startSession): creates a new `ClientSession` instance

- [startTransaction()](https://mongodb.github.io/node-mongodb-native/7.7/classes/ClientSession.html#startTransaction): starts a new transaction

- [commitTransaction()](https://mongodb.github.io/node-mongodb-native/7.7/classes/ClientSession.html#commitTransaction): commits the active transaction in the session that it was created in

- [abortTransaction()](https://mongodb.github.io/node-mongodb-native/7.7/classes/ClientSession.html#abortTransaction): ends the active transaction in the session that it was created in

- [endSession()](https://mongodb.github.io/node-mongodb-native/7.7/classes/ClientSession.html#endSession): ends the active session

You must perform the following steps when using this API:

- Pass the session instance to each operation that you want to run in that session.

- Implement a `catch` block in which you identify server transaction errors and implement error-handling logic.

The following code demonstrates how to perform a transaction by using the Core API:

```javascript
async function coreTest(client) {
  const session = client.startSession();
  try {
    session.startTransaction();

    const savingsColl = client.db("bank").collection("savings_accounts");
    await savingsColl.findOneAndUpdate(
      {account_id: "9876"}, 
      {$inc: {amount: -100 }}, 
      { session });

    const checkingColl = client.db("bank").collection("checking_accounts");
    await checkingColl.findOneAndUpdate(
      {account_id: "9876"}, 
      {$inc: {amount: 100 }}, 
      { session });

    // ... perform other operations

    await session.commitTransaction();
    console.log("Transaction committed.");
  } catch (error) {
    console.log("An error occurred during the transaction:" + error);
    await session.abortTransaction();
  } finally {
    await session.endSession();
  }
}
```

**Important: Use a Session with the Client That Started It**

The driver throws an error if you provide a session from one `MongoClient` instance to a different client instance.

For example, the following code generates an `MongoInvalidArgumentError` error because it creates a `ClientSession` instance from the `client1` client, but provides this session to the `client2` client for a write operation:

```js
const session = client1.startSession();
client2.db('myDB').collection('myColl').insertOne({ name: 'Jane Eyre' }, { session });
```

**Tip: Explicit Resource Management**

The Node.js driver natively supports explicit resource management for `MongoClient`, `ClientSession`, `ChangeStreams`, and cursors. This feature is experimental and subject to change. To learn how to use explicit resource management, see the [v6.9 Release Notes.](https://github.com/mongodb/node-mongodb-native/releases/tag/v6.9.0)

To see a fully runnable example that uses this API, see the [Use the Core API](https://www.mongodb.com/docs/drivers/node/current/crud/transactions/transaction-core.md#std-label-node-usage-core-txn) usage example.

### Convenient Transaction API

The Convenient Transaction API provides the following methods to implement transactions:

- [withSession()](https://mongodb.github.io/node-mongodb-native/7.7/classes/MongoClient.html#withSession): Runs the callback passed to it within a session. The API handles the creation and termination of the session automatically.

- [withTransaction()](https://mongodb.github.io/node-mongodb-native/7.7/classes/ClientSession.html#withTransaction): Runs the callback passed to it within a transaction and calls the `commitTransaction()` method when the callback returns.

These methods return the value that the callback returns. For example, if a callback you pass to the `withTransaction()` method returns the document `{ hello: "world" }`, then the `withTransaction()` method also returns that document.

**Important:**

To avoid infinite looping errors, ensure that the callback you pass to the `withTransaction()` method catches any errors that it raises.

When you use the Convenient Transaction API, you can propagate return values from the callback as the return values of the `withTransaction()` and `withSession()` methods to work with them elsewhere in your code.

You must perform the following steps when using this API:

- Pass the session instance to each operation that you want to run in that session.

- Implement the async `await` syntax for each operation in the session.

- Avoid parallelism, such as calling the `Promise.all()` method. Using sessions in parallel usually leads to server errors.

The following code demonstrates how to perform a transaction by using the Convenient Transaction API:

```javascript
async function convTest(client) {
  let txnRes = await client.withSession(async (session) =>
    session.withTransaction(async (session) => {
      const savingsColl = client.db("bank").collection("savings_accounts");
      await savingsColl.findOneAndUpdate(
        {account_id: "9876"}, 
        {$inc: {amount: -100 }}, 
        { session });
  
      const checkingColl = client.db("bank").collection("checking_accounts");
      await checkingColl.findOneAndUpdate(
        {account_id: "9876"}, 
        {$inc: {amount: 100 }}, 
        { session });

      // ... perform other operations

      return "Transaction committed.";
    }, null)
  );
  console.log(txnRes);
}
```

To see a fully runnable example that uses this API, see the [Use the Convenient Transaction API](https://www.mongodb.com/docs/drivers/node/current/crud/transactions/transaction-conv.md#std-label-node-usage-convenient-txn) usage example.

**Note: Parallel Operations Not Supported**

The Node.js driver does not support running parallel operations within a single transaction.

## Transaction Options

You can pass a `TransactionOptions` instance to the `startTransaction()` and `withTransaction()` methods to configure how the driver performs a transaction. When you specify an option, it overrides the value of the option that you might have set on your `MongoClient` instance.

The following table includes options that you can specify in a `TransactionOptions` instance:

| Setting | Description |
| --- | --- |
| `readConcern` | Specifies read operation consistency of the replica set.To learn more, see [Read Concern](https://www.mongodb.com/docs/manual/reference/read-concern/) in the Server manual. |
| `writeConcern` | Specifies the write operation level of acknowledgment required from a replica set.To learn more, see [Write Concern](https://www.mongodb.com/docs/manual/reference/write-concern/) in the Server manual. |
| `readPreference` | Specifies how to route read operations to members of a replica set.To learn more, see [Read Preference](https://www.mongodb.com/docs/manual/core/read-preference/#read-preference) in the Server manual. |
| `maxCommitTimeMS` | Specifies the length of time that a commit action on a transaction can run, in milliseconds. |

For a full list of options, see the API documentation for [TransactionOptions.](https://mongodb.github.io/node-mongodb-native/7.7/interfaces/TransactionOptions.html)

**Note:**

The transaction inherits settings from your `MongoClient` instance unless you specify them in your transaction options.

The following code shows how to define and pass transaction options to the `startTransaction()` method:

```javascript
const txnOpts = {
  readPreference: 'primary',
  readConcern: { level: 'local' },
  writeConcern: { w: 'majority' },
  maxCommitTimeMS: 1000
};
session.startTransaction(txnOpts);
```

## Transaction Errors

Because MongoDB transactions are [ACID compliant](https://www.mongodb.com/basics/acid-transactions?tck=docs), the driver might produce errors during operation to ensure your data maintains consistent. If the following errors occur, your application must retry the transaction:

- `TransientTransactionError`: Raised if a write operation encounters an error before the driver commits the transaction. To learn more about this error type, see the [TransientTransactionError description](https://www.mongodb.com/docs/manual/core/transactions-in-applications/#transienttransactionerror) on the Drivers API page in the Server manual.

- `UnknownTransactionCommitResult`: Raised if the commit operation encounters an error. To learn more about this error type, see the [UnknownTransactionCommitResult description](https://www.mongodb.com/docs/manual/core/transactions-in-applications/#unknowntransactioncommitresult) on the Drivers API page in the Server manual.

The following sections describe how to handle these errors when using different APIs.

### Convenient Transaction API Error Handling

The Convenient Transaction API incorporates retry logic for these error types. The driver automatically retries the transaction until there is a successful commit.

### Core API Error Handling

If you are using the Core API to perform a transaction, you must add the following error-handling functions to your application:

- A function that retries the entire transaction when the driver encounters a `TransientTransactionError`

- A function that retries the commit operation when the driver encounters an `UnknownTransactionCommitResult`

These functions must run until there is a successful commit or a different error. For an example of this retry logic, see the [Core API section](https://www.mongodb.com/docs/manual/core/transactions-in-applications/#core-api) on the Drivers API page in the Server manual.
