Amazon DynamoDB
Developer Guide (API Version 2012-08-10)

Amazon DynamoDB Transactions: How it Works

With Amazon DynamoDB transactions, you can group multiple actions together and submit them as a single all-or-nothing TransactWriteItems or TransactGetItems operation. The following sections describe API operations, capacity management, best practices, and other details about using transactional operations in DynamoDB.

TransactWriteItems API

TransactWriteItems is a synchronous and idempotent write operation that groups up to 10 write actions in a single all-or-nothing operation. These actions can target up to 10 distinct items in one or more DynamoDB tables within the same AWS account and in the same Region. The actions are completed atomically so that either all of them succeed or none of them succeeds.

A TransactWriteItems operation differs from a BatchWriteItem operation in that all the actions it contains must be completed successfully, or no changes are made at all. With a BatchWriteItem operation, it is possible that only some of the actions in the batch succeed while the others do not.

You cannot target the same item with multiple operations within the same transaction. For example, you cannot perform a ConditionCheck and also an Update action on the same item in the same transaction.

You can add the following types of actions to a transaction:

  • Put — Initiates a PutItem operation to create a new item or replace an old item with a new item, conditionally or without specifying any condition.

  • Update — Initiates an UpdateItem operation to edit an existing item's attributes or add a new item to the table if it does not already exist. Use this action to add, delete, or update attributes on an existing item conditionally or without a condition.

  • Delete — Initiates a DeleteItem operation to delete a single item in a table identified by its primary key.

  • ConditionCheck — Checks that an item exists or checks the condition of specific attributes of the item.

Changes made with transactions are propagated to global secondary indexes (GSIs), DynamoDB streams, and backups eventually, after the transaction completes successfully. Because of eventual consistency, tables restored from an on-demand or point-in-time-recovery (PITR) backup might contain some but not all of the changes made by a recent transaction.

Idempotency

You can optionally include a client token when you make a TransactWriteItems call to ensure that the request is idempotent. Making your transactions idempotent helps prevent application errors if the same operation is submitted multiple times due to a connection time-out or other connectivity issue.

If the original TransactWriteItems call was successful, then subsequent TransactWriteItems calls with the same client token return successfully without making any changes. If the ReturnConsumedCapacity parameter is set, then the initial TransactWriteItems call returns the number of write capacity units consumed in making the changes. Subsequent TransactWriteItems calls with the same client token return the number of read capacity units consumed in reading the item.

Important Points about Idempotency

  • A client token is valid for 10 minutes after the request that uses it finishes. After 10 minutes, any request that uses the same client token is treated as a new request. You should not reuse the same client token for the same request after 10 minutes.

  • If you repeat a request with the same client token within the 10-minute idempotency window but change some other request parameter, DynamoDB returns an IdempotentParameterMismatch exception.

Error Handling for Writing

Write transactions don't succeed under the following circumstances:

  • When a condition in one of the condition expressions is not met.

  • When a transaction validation error occurs because more than one action in the same TransactWriteItems operation targets the same item.

  • When an ongoing TransactWriteItems operation conflicts with a concurrent TransactWriteItems request on one or more items in the TransactWriteItems operation. In this case, the concurrent request fails with a TransactionCancelledException.

  • When there is insufficient provisioned capacity for the transaction to be completed.

  • When an item size becomes too large (larger than 400 KB), or a local secondary index (LSI) becomes too large, or a similar validation error occurs because of changes made by the transaction.

  • When there is a user error, such as an invalid data format.

If an ongoing TransactWriteItems operation conflicts with a concurrent PutItem, UpdateItem, DeleteItem, or TransactGetItems request on one or more items in the TransactWriteItems operation, then the concurrent request fails with a TransactionCancelledException.

However, if an ongoing TransactWriteItems operation conflicts with a concurrent GetItem request, both operations can succeed.

TransactGetItems API

TransactGetItems is a synchronous read operation that groups up to 10 Get actions together. These actions can target up to 10 distinct items in one or more DynamoDB tables within the same AWS account and Region.

The Get actions are performed atomically so that either all of them succeed or all of them fail:

  • Get — Initiates a GetItem operation to retrieve a set of attributes for the item with the given primary key. If no matching item is found, Get does not return any data.

Error Handling for Reading

Read transactions don't succeed under the following circumstances:

  • When there is an ongoing TransactGetItems operation that conflicts with a concurrent PutItem, UpdateItem, DeleteItem or TransactWriteItems request. In this case the TransactGetItems operation fails with a TransactionCancelledException.

  • When there is insufficient provisioned capacity for the transaction to be completed.

  • When there is a user error, such as an invalid data format.

However, if an ongoing TransactGetItems operation conflicts with a concurrent GetItem request, both operations can succeed.

Isolation Levels for DynamoDB Transactions

The isolation levels of transactional operations (TransactWriteItems or TransactGetItems) and other operations are as follows:

SERIALIZABLE

Serializable isolation ensures that the results of multiple concurrent operations are the same as if no operation begins until the previous one has finished.

There is serializable isolation between the following types of operation:

  • Between any transactional operation and any standard write operation (PutItem, UpdateItem, or DeleteItem).

  • Between any transactional operation and any standard read operation (GetItem).

  • Between a TransactWriteItems operation and a TransactGetItems operation.

Although there is serializable isolation between transactional operations, and each individual standard writes in a BatchWriteItem operation, there is no serializable isolation between the transaction and the BatchWriteItem operation as a unit.

Similarly, the isolation level between a transactional operation and individual GetItems in a BatchGetItem operation is serializable, but the isolation level between the transaction and the BatchGetItem operation as a unit is read-committed.

READ-COMMITTED

Read-committed isolation ensures that read operations always return committed values for an item. Read-committed isolation does not prevent modifications of the item immediately after the read operation.

The isolation level is read-committed between any transactional operation and any read operation that involves multiple standard reads (BatchGetItem, Query, or Scan). If a transactional write updates an item in the middle of a BatchGetItem, Query, or Scan operation, the read operation returns the new committed value.

Summary Table

To summarize, the following table shows the isolation levels between a transaction operation (TransactWriteItems or TransactGetItems) and other operations.

Operation Isolation Level

DeleteItem

Serializable

PutItem

Serializable

UpdateItem

Serializable

GetItem

Serializable

BatchGetItem

Read-committed*

BatchWriteItem

NOT Serializable*

Query

Read-committed

Scan

Read-committed

Other transactional operation

Serializable

Levels marked with an asterisk (*) apply to the operation as a unit. However, individual actions within those operations have a serializable isolation level.

Capacity Management for Transactions

There is no additional cost to enable transactions for your DynamoDB tables. You pay only for the reads or writes that are part of your transaction. DynamoDB performs two underlying reads or writes of every item in the transaction: one to prepare the transaction and one to commit the transaction. The two underlying read/write operations are visible in your Amazon CloudWatch metrics.

Plan for the additional reads and writes required by transactional APIs when you are provisioning capacity to your tables. For example, suppose that your application executes one transaction per second, and each transaction writes three 500-byte items in your table. Each item requires two write capacity units (WCUs): one to prepare the transaction and one to commit the transaction. Therefore, you would need to provision six WCUs to the table.

Similarly, if your application executes one read transaction per second and each transaction reads three 500-byte items in your table, you would need to provision six read capacity units (RCUs) to the table. Reading each item require two RCUs: one to prepare the transaction and one to commit the transaction.

Also, default SDK behavior is to retry transactions in case of a TransactionInProgressException exception. Plan for the additional read-capacity units (RCUs) that these retries consume. The same is true if you are retrying transactions in your own code using a ClientRequestToken.

Best Practices for Transactions

Consider the following recommended practices when using DynamoDB transactions.

  • Enable auto scaling on your tables, or ensure that you have provisioned enough throughput capacity to perform the two read or write operations for every item in your transaction.

  • If you are not using an AWS provided SDK, include a ClientRequestToken attribute when you make a TransactWriteItems call to ensure that the request is idempotent.

  • Don't group operations together in a transaction if it's not necessary. For example, if a single transaction with 10 operations can be broken up into multiple transactions without compromising the application correctness, we recommend splitting up the transaction. Simpler transactions improve throughput and are more likely to succeed.

  • Multiple transactions updating the same items simultaneously can cause conflicts that cancel the transactions. We recommend following DynamoDB best practices for data modeling to minimize such conflicts.

  • If a set of attributes is often updated across multiple items as part of a single transaction, consider grouping the attributes into a single item to reduce the scope of the transaction.

  • Avoid using transactions for ingesting data in bulk. For bulk writes, it is better to use BatchWriteItem.

Integration with Other DynamoDB Features

The following DynamoDB features currently do not support DynamoDB transactions:

  • Transactional operations are disabled for global tables by default. Contact Amazon Support if you want to enable transactions on global tables.

  • Transactional operations are not supported by DynamoDB Accelerator (DAX), DynamoDB local, or DynamoDB Mapper at this time.

DynamoDB Transactions vs. the AWSLabs Transactions Client Library

DynamoDB transactions provide a more cost-effective, robust, and performant replacement for the AWSLabs transactions client library. We suggest that you update your applications to use the native, server-side transaction APIs.