DynamoDB TransactWriteItems in Node.js (AWS SDK v3)

TransactWriteItems groups up to 100 writes into one all-or-nothing operation — either every action commits, or none do. In AWS SDK v3 you send a TransactWriteItemsCommand whose TransactItems array mixes Put, Update, Delete, and ConditionCheck actions, each with an optional condition.

Code

import {DynamoDBClient, TransactWriteItemsCommand} from '@aws-sdk/client-dynamodb';

const client = new DynamoDBClient({region: 'us-east-1'});

// Move one award between two songs — atomically. If the first song has no
// award to give, NEITHER update happens.
const command = new TransactWriteItemsCommand({
  TransactItems: [
    {
      Update: {
        TableName: 'Music',
        Key: {Artist: {S: 'Arturo Sandoval'}, SongTitle: {S: 'Cubano Chant'}},
        UpdateExpression: 'SET #upd0 = #upd0 - :one',
        ConditionExpression: '#upd0 >= :one',
        ExpressionAttributeNames: {'#upd0': 'Awards'},
        ExpressionAttributeValues: {':one': {N: '1'}}
      }
    },
    {
      Update: {
        TableName: 'Music',
        Key: {Artist: {S: 'Arturo Sandoval'}, SongTitle: {S: 'A Mis Abuelos'}},
        UpdateExpression: 'SET #upd0 = if_not_exists(#upd0, :zero) + :one',
        ExpressionAttributeNames: {'#upd0': 'Awards'},
        ExpressionAttributeValues: {':one': {N: '1'}, ':zero': {N: '0'}}
      }
    }
  ]
});

try {
  await client.send(command);
  console.log('Transaction committed');
} catch (err) {
  if (err.name === 'TransactionCanceledException') {
    // One reason per action, in TransactItems order. 'None' means that action
    // was fine — some OTHER action sank the transaction.
    const codes = (err.CancellationReasons ?? []).map((r) => r.Code);
    console.log('Transaction canceled:', codes); // e.g. ['ConditionalCheckFailed', 'None']
  } else {
    throw err;
  }
}

Explanation

  • TransactItems — up to 100 Put / Update / Delete / ConditionCheck actions, 4 MB aggregate. Actions can span tables (same account + Region), but no two actions may target the same item — that alone cancels the transaction.
  • ConditionCheck — asserts a condition on an item the transaction does not modify (e.g. "the account still exists") and vetoes the whole transaction if it fails.
  • TransactionCanceledException — the one error to handle. err.CancellationReasons lists one {Code, Message} per action in order — codes include ConditionalCheckFailed, TransactionConflict (another transaction touched an item mid-flight — safe to retry with backoff), ProvisionedThroughputExceeded, and ValidationError; None marks the innocent actions. Set ReturnValuesOnConditionCheckFailure: 'ALL_OLD' on an action to get the losing item's attributes in its reason.
  • ClientRequestToken — pass one to make the call idempotent for 10 minutes; an SDK retry after a network timeout then can't apply the writes twice.
  • Cost — transactional writes consume two underlying writes per item (prepare + commit), so they bill roughly 2× the WCUs of a plain write. Don't reach for transactions when a single-item conditional write already gives you atomicity on one item.

Do it visually

The condition and update expressions inside each action are the fiddly part — the DynamoDB Expression Builder assembles them with the name/value maps and copies runnable code.

To edit items and review the generated expressions in a GUI — download DynoTable.

References

Last verified 2026-07-13 against the official AWS documentation linked above.

Work with DynamoDB without the Console

DynoTable is a fast desktop client for DynamoDB — browse tables, run SQL-style queries, and edit items locally.