用 AWS CLI 執行 DynamoDB TransactWriteItems
整筆交易是以一個 --transact-items JSON 陣列送進 aws dynamodb transact-write-items 的,所以有趣的部分在 CLI 的邊角:引號會在哪裡壞掉、結束碼是什麼意思,以及預設的錯誤輸出會把你除錯取消原因時最需要的那個欄位丟掉。交易替你買到了什麼在每一套 SDK 裡都是一樣的。
程式碼
aws dynamodb transact-write-items \
--transact-items '[
{
"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"}}
}
}
]'已提交的交易什麼都不會印,並以 0 結束。沒有回應主體可以檢查,所以在腳本裡,結束碼就是結果。
說明
--transact-items— 最多 100 個Put/Update/Delete/ConditionCheck動作,總量 4 MB,值用 DynamoDB JSON。這些動作可以橫跨同一帳戶與同一區域內的多張資料表,而其中任兩個都不可以指向同一個項目。三種結束碼,三種不同的失敗。
0是提交成功。252代表 CLI 自己的參數驗證回絕了這個請求,什麼都沒送出去。254代表 DynamoDB 回答了,而它說不行。這個區別值得拿來分支:252 是你 JSON 裡的臭蟲,254 則可能是一個你本來就預期會失敗的條件。預設的錯誤格式會把每個動作的原因丟掉。aws-cli v2 印出摘要,然後告訴你它把細節扣住了:
aws: [ERROR]: An error occurred (TransactionCanceledException) when calling the TransactWriteItems operation: Transaction cancelled, please refer cancellation reasons for specific reasons [ConditionalCheckFailed, None] Additional error details: CancellationReasons: <complex value> Use "--cli-error-format json" or another error format to see the full details.用
--cli-error-format json重跑同一條指令,結構就會完整抵達,每個動作一筆,順序與--transact-items相同:{ "Message": "Transaction cancelled, please refer cancellation reasons for specific reasons [ConditionalCheckFailed, None]", "Code": "TransactionCanceledException", "CancellationReasons": [ { "Code": "ConditionalCheckFailed", "Message": "The conditional request failed" }, { "Code": "None" } ] }這裡是第一個 update 的
Awards >= 1條件失敗了;None標示第二個動作是無辜的,而且請注意它根本沒有帶Message欄位。其餘每一個代碼都在 TransactionCanceledException 頁面上解碼。對同一個項目下手兩次不算取消。它在任何動作被嘗試之前就沒通過驗證,這也是為什麼根本沒有原因可以印:
aws: [ERROR]: An error occurred (ValidationException) when calling the TransactWriteItems operation: Transaction request cannot include multiple operations on one itemConditionCheck— 對一個交易並不修改的項目主張某個條件,若它失敗就否決整筆交易。--client-request-token— 固定的 token 會讓重跑在 10 分鐘內具備冪等性。用同一個 token 卻改了任何參數,DynamoDB 會回IdempotentParameterMismatch,而不是默默套用新的酬載。把陣列放進檔案。
--transact-items file://transaction.json完全避開 shell 引號問題,而且檔案可以 diff。
那個 2× 從 shell 就量得出來
把同一次單一項目的更新跑兩遍,一次在交易裡、一次在交易外,兩次都帶 --return-consumed-capacity TOTAL。DynamoDB Local 對交易式寫入回報 2.0 個容量單位,對普通寫入回報 1.0:準備與提交各自都要計費。
這就是「別預設就伸手去拿交易」的全部論據。要在單一項目上取得不可分割性,你手上已經有一個更便宜的工具 — 條件式寫入,它只計費一次。若要替一個會做上百萬次這種事的工作負載估價,DynamoDB 定價計算機可以直接吃下那個翻倍後的寫入次數。如果你想停手的是在 shell 裡組 DynamoDB JSON 這件事,DynoTable 能對真實資料表編輯項目,並把它產生的運算式顯示給你看。
相關範例
- Node.js 中的 DynamoDB TransactWriteItems — 用 AWS SDK v3 做同一筆交易。
- Python 中的 DynamoDB TransactWriteItems — 用 boto3 做同一筆交易。
- 用 AWS CLI 執行 DynamoDB BatchWriteItem — 不需要不可分割性時的大量寫入。
- DynamoDB 交易 — 隔離性、冪等性,以及交易值得動用的時機。
- DynamoDB TransactionCanceledException — 每一個取消原因代碼的解讀。
- 「Too many actions in a TransactWriteItems call」 — 交易的 100 個動作與 4 MB 限制。
- 「Transaction request cannot include multiple operations on one item」 — 每筆交易、每個項目只能有一個動作。
參考資料
- TransactWriteItems — Amazon DynamoDB API Reference
- transact-write-items — AWS CLI Command 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-28,對照上方連結的 AWS 官方文件。