在 Node.js(AWS SDK v3)中使用 DynamoDB TransactWriteItems

TransactWriteItems 把多達 100 個寫入組成一個全有或全無的操作 — 要嘛每個動作都提交,要嘛都不。在 AWS SDK v3 中,你送出一個 TransactWriteItemsCommand,其 TransactItems 陣列混合 PutUpdateDeleteConditionCheck 動作,每個都可帶一個選用的條件。

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;
  }
}

說明

  • TransactItems — 多達 100 個 Put / Update / Delete / ConditionCheck 動作,合計 4 MB。動作可橫跨表格(同一帳戶 + Region),但沒有兩個動作可鎖定同一個項目 — 光是這樣就會取消交易。
  • ConditionCheck — 對交易修改的項目斷言一個條件(例如「帳戶仍存在」),若失敗則否決整個交易。
  • TransactionCanceledException — 唯一需要處理的錯誤。err.CancellationReasons 依序列出每個動作的一個 {Code, Message} — code 包括 ConditionalCheckFailedTransactionConflict(另一個交易在過程中觸及某個項目 — 以退避安全重試)、ProvisionedThroughputExceededValidationErrorNone 標記無辜的動作。在某個動作上設定 ReturnValuesOnConditionCheckFailure: 'ALL_OLD',可在其原因中取得敗方項目的屬性。
  • ClientRequestToken — 傳入一個 token 讓呼叫在 10 分鐘內具冪等性;網路逾時後的 SDK 重試也無法把寫入套用兩次。
  • 成本 — 交易式寫入每個項目消耗兩個底層寫入(準備 + 提交),因此計費約為一般寫入 WCU 的 2×。當單一項目的 條件式寫入 已能給你單一項目的 atomic 性時,別動用交易。

改用視覺化操作

每個動作裡的條件與 update 運算式是繁瑣的部分 — DynamoDB Expression Builder 會連同 name/value map 一起組裝它們並複製可執行的程式碼。

想在 GUI 中編輯項目並審視產生的運算式 — 下載 DynoTable

相關範例

References

最後驗證於 2026-07-13,對照上方連結的 AWS 官方文件。

不必透過主控台就能操作 DynamoDB

DynoTable 是一款快速的 DynamoDB 桌面用戶端 — 瀏覽表格、執行 SQL 風格的查詢,並在本機編輯項目。