DynamoDB Transactions - The Ultimate Guide (w/ Examples)
Tags: dynamodb, aws, serverless
Published: 2022-03-05 20:36:07

---
title: DynamoDB Transactions - The Ultimate Guide (w/ Examples)
published: true
description: Learn everything you need to know about what AWS DynamoDB Transactions are, their use cases, and how to use them.
tags: dynamodb,aws,serverless
canonical_url: https://dynobase.com/dynamodb-transactions/
---

DynamoDB supports classical ACID transactions. But let's start with the basics.

## What is ACID Transaction?

Wikipedia says:

> A **database transaction** symbolizes a unit of work performed within a [database management system](https://en.wikipedia.org/wiki/Database_management_system) (or similar system) against a database and treated coherently and reliably independent of other transactions. A transaction generally represents any change in a database.

Let me explain a "transaction" to you using more human terms:

> Imagine it's Saturday. You're going to the bar with a strict entry policy with two of your friends. As you approach the bar, the bouncer looks at your first friend and lets him in. Then, he looks at you and lets you in. Finally, he looks at your second friend and says: _"Sorry, it's not your day"_, and he is not letting him in. Because you are good friends and you always support each other, in the act of solidarity, you and your friend who managed to get in decide to leave the bar. _One for all, all for one_, like _Three Musketeers_. In transaction terms, you decided to "rollback".

> Next Saturday, you're going to the same bar, but this time you got lucky, and all three of you managed to get in, and nobody needs to leave. Congrats! In the transactions world, this is a "committed" transaction.

Transactions in database world have four basic properties:

- **Atomicity**: Guarantees that a transaction is either fully committed or not at all. Each transaction is a single unit of change to the database and it is either committed or rolled back.
- **Consistency**: Guarantees that the database is in a consistent state after a transaction is committed.
- **Isolation**: Guarantees that a transaction is executed in a way that does not affect other transactions.
- **Durability**: Guarantees that a transaction is committed even if the system fails.

#### Translating this story to a more technical jargon

Transactions are groups of read or write operations performed atomically (multiple statements are treated as one), consistently (state after transaction will be valid), in insolation (ensures concurrent transactions are executed like sequentially) and durable (once the transaction has been committed, you can be sure that it has been persisted to the table).

## Why Transactions are important

Transactions are super useful when dealing with mission-critical data like currency, item stocks, or, generally speaking - resources. Imagine implementing a banking system, sending money from account `A` to `B`. In your first naive implementation, you first subtract money from account `A`, and then add it to account `B`. It might sound totally correct.

However, there is a chance that your application will crash between the first and second operation. Or that second operation was rejected. This will render your application state corrupted, and a portion of the money would be lost in-flight.

Transactions prevent problems like this one from happening. In your application, the operation of both subtracting money from account `A`, and adding it to the account `B`, would be treated as one indivisible call. There's no possibility of your code crashing between calls, and if the second operation is rejected, the first calculation is rollbacked too. It's always all-or-nothing.

Other use cases for transactions include:

- Maintaining uniqueness
- Checking idempotency
- Restricting actions depending on permissions

## How to do transactions in DynamoDB using Node.js

Since we already know why it is important, the chances are that you've identified such patterns in your application, and you would like to implement them. Here's how you can implement a simple transaction against DynamoDB [using Node.js](/dynamodb-nodejs/):

```javascript
const AWS = require("aws-sdk");
const dynamoDB = new AWS.DynamoDB.DocumentClient({ region:'us-east-1' });

await dynamoDB.transactWrite({
  TransactItems: [
    {
      Put: { // Write an item to the Cart table
        Item: { // Actual Item
          id: '777',
          count: '1',
          description: 'Lorem ipsum...'
        }
        TableName: "Cart",
      },
    },
    {
      Update: { // Decrement count of items available to buy only if the count is greater than zero
        ConditionExpression: "#count > 0",
        ExpressionAttributeNames: { "#count": "count" },
        ExpressionAttributeValues: {
         ":value": 1,
        },
        Key: {
         id: '777-000',
        }
        TableName: "Items",
        UpdateExpression: "SET #count = :count - :value",
        },
      },
    ],
  }).promise();
```

### Let's break it down

To create a transaction in DynamoDB, you can use `documentClient.transactWrite`.
0 It takes a parameter with `TransactItems` property - an Array of operations that should be performed.

- Each of this array items must have a one of top-level property:
  - `Put` - Inserts an item into the table. Use the same syntax as in [put](https://dynobase.dev/dynamodb-nodejs/#put-item) operation
  - `Update` - Updates an item from the table. Use the same syntax as in [update](https://dynobase.dev/dynamodb-nodejs/#update-item) operation. Inside it, you can write `ConditionExpressions` to update item conditionally. If condition is not met, whole transaction is rollbacked.
  - `Delete` - Deletes an item from the table. Use the same syntax as in [delete](https://dynobase.dev/dynamodb-nodejs/#delete-item) operation
  - `ConditionCheck` - A condition to an item that is not being modified by the transaction. Like in `Update`, if this one is not met, whole transaction is rejected.
- To use modern ES syntax, whole expression is ended with a `.promise()` call and `await`ed on.

This illustrates a _write_ transaction. What if you wanted to _read_ items using transaction? Well, [that's also possible](https://dynobase.com/dynamodb-nodejs/#read-transaction).

## Error handling

Transactions can be cancelled for a multiple reasons:

- `ConditionalCheckFailed` - the `ConditionExpression` in one of the items wasn't met so the whole transaction is rolled back
- `TransactionConflict` - the transaction was rejected because of a conflict with another ongoing transaction
- `ValidationError` - the transaction was rejected because of a validation error, someparameters might be invalid, some updates might update keys beyond allowed limits, item size might exceed 400Kb, there might be a mismatch between operand in the update expression and the type, and so on.
- `TransactionInProgressException` - the transaction was rejected because another transaction with the same request token is already in progress

## Limits and Caveats

- Transaction operations have the same limitations as they have in a normal form. For example, the size of the item inserted must be [smaller than 400KB](https://dynobase.dev/dynamodb-capacity-and-item-size-calculator/).
- Total size of all the items used in the transaction must be [smaller than 4MB](https://dynobase.dev/dynamodb-limits/).
- If there's another transaction in progress updating the same item, any other transactions will be rejected.
- `TransactItems` can only have up to 25 operations. Note that they can target multiple tables.
- Each of the `TransactItems` operations can use a different table! Yes, you can do multi-table transactions.
- Transactions are not incurring any additional [costs](https://dynobase.dev/dynamodb-pricing-calculator/).

### Further reading

- Brilliant article by [Alex DeBrie on DynamoDB Transactions](https://www.alexdebrie.com/posts/dynamodb-transactions/)
- [DynamoDB and Node.js Complete Guide](/dynamodb-nodejs/)
- [Mastering Amazon DynamoDB ACID Transactions](https://pages.awscloud.com/Mastering-Amazon-DynamoDB-ACID-Transactions-When-and-How-to-Use-the-New-Transactional-APIs_2019_0410-DAT_OD.html)