Free — no signup required

Transactions and Conditional Writes

2 min read

When Atomicity Matters

DynamoDB is not a relational database, but it does support atomic operations — critical for financial systems, inventory management, and any scenario where partial updates would leave data in an inconsistent state.

Conditional Writes

A conditional write succeeds only if a specified condition is true at the moment of execution. If the condition fails, the write is rejected with a ConditionalCheckFailedException — no data is modified.

Use case: Optimistic locking

# Only update the item if the version number hasn't changed
# (another writer hasn't modified it since we read it)
table.update_item(
    Key={"PK": "PRODUCT#abc", "SK": "DETAILS"},
    UpdateExpression="SET Stock = Stock - :qty, Version = Version + :one",
    ConditionExpression="Version = :expected_version AND Stock >= :qty",
    ExpressionAttributeValues={
        ":qty": 1,
        ":one": 1,
        ":expected_version": 5  # the version we read
    }
)

If two users try to buy the last item simultaneously, only one succeeds. The other gets ConditionalCheckFailedException and must retry. This is optimistic concurrency control — no locks are held, so throughput remains high.

Use case: Prevent duplicate creation

# Only create the item if it doesn't already exist
table.put_item(
    Item={"PK": "USER#[email protected]", "SK": "PROFILE", "Name": "Alice"},
    ConditionExpression="attribute_not_exists(PK)"
)

This guarantees idempotent user creation — calling this twice with the same email will succeed the first time and fail the second, preventing duplicate accounts.

TransactWriteItems: Multi-Item Atomicity

TransactWriteItems allows up to 100 items across up to 100 different tables to be written atomically — all succeed or all fail together.

A TransactWriteItems call bundles the debit, the credit, and an audit record into a single list of operations — each entry is an Update or Put with its own ConditionExpression (a Balance >= :amount check on the debit to prevent overdraft, an attribute_not_exists(PK) check on the transaction record to reject duplicate transfers) — and DynamoDB commits or rejects the entire list as one atomic unit.

This transfers $50 from Alice to Bob and records the transaction — atomically. If Alice's balance check fails, neither balance changes and no transaction record is created.

Cost: Transactions cost 2× the normal WCU/RCU rate. A transaction touching 3 items that are each 1 KB costs 6 WCUs (3 items × 1 WCU × 2 transaction multiplier). Factor this into capacity planning for transaction-heavy workloads.

Limitation: All items in a transaction must be in the same AWS region. Cross-region transactions are not supported.

This is one of 18 chapters

Get every chapter — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

See pricing