在 Node.js(AWS SDK v3)中使用 DynamoDB TransactWriteItems
TransactWriteItems 把多達 100 個寫入組成一個全有或全無的操作 — 要嘛每個動作都提交,要嘛都不。在 AWS SDK v3 中,你送出一個 TransactWriteItemsCommand,其 TransactItems 陣列混合 Put、Update、Delete 與 ConditionCheck 動作,每個都可帶一個選用的條件。
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 包括ConditionalCheckFailed、TransactionConflict(另一個交易在過程中觸及某個項目 — 以退避安全重試)、ProvisionedThroughputExceeded與ValidationError;None標記無辜的動作。在某個動作上設定ReturnValuesOnConditionCheckFailure: 'ALL_OLD',可在其原因中取得敗方項目的屬性。ClientRequestToken— 傳入一個 token 讓呼叫在 10 分鐘內具冪等性;網路逾時後的 SDK 重試也無法把寫入套用兩次。- 成本 — 交易式寫入每個項目消耗兩個底層寫入(準備 + 提交),因此計費約為一般寫入 WCU 的 2×。當單一項目的 條件式寫入 已能給你單一項目的 atomic 性時,別動用交易。
改用視覺化操作
每個動作裡的條件與 update 運算式是繁瑣的部分 — DynamoDB Expression Builder 會連同 name/value map 一起組裝它們並複製可執行的程式碼。
想在 GUI 中編輯項目並審視產生的運算式 — 下載 DynoTable。
相關範例
- 在 Python 中使用 DynamoDB TransactWriteItems — 以 boto3 執行相同的交易。
- 使用 AWS CLI 執行 DynamoDB TransactWriteItems — 從 shell 執行相同的交易。
- 在 Node.js 中執行 DynamoDB 條件式寫入 — 沒有 2× 成本的單一項目 atomic 性。
- DynamoDB 交易 — 隔離、冪等性,以及何時交易值得。
- DynamoDB TransactionCanceledException — 每個取消原因 code 的解碼。
- "Too many actions in a TransactWriteItems call" — 100 個動作與 4 MB 的交易上限。
- "Transaction request cannot include multiple operations on one item" — 每個交易中每個項目只能有一個動作。
References
- TransactWriteItems — Amazon DynamoDB API Reference
- Amazon DynamoDB transactions: how it works — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
最後驗證於 2026-07-13,對照上方連結的 AWS 官方文件。