在 Python(boto3)中使用 DynamoDB TransactWriteItems
transact_write_items 把多達 100 個寫入組成一個全有或全無的操作 — 要嘛每個動作都提交,要嘛都不。使用 boto3 低階 client 時,你傳入一個混合 Put、Update、Delete 與 ConditionCheck 動作的 TransactItems list,每個都可帶一個選用的條件。
Code
import boto3
client = boto3.client("dynamodb")
# Move one award between two songs — atomically. If the first song has no
# award to give, NEITHER update happens.
try:
client.transact_write_items(
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"}},
}
},
]
)
print("Transaction committed")
except client.exceptions.TransactionCanceledException as e:
# One reason per action, in TransactItems order. Code "None" means that
# action was fine — some OTHER action sank the transaction.
codes = [reason["Code"] for reason in e.response["CancellationReasons"]]
print(f"Transaction canceled: {codes}") # e.g. ['ConditionalCheckFailed', 'None']說明
TransactItems— 多達 100 個Put/Update/Delete/ConditionCheck動作,合計 4 MB,值為 DynamoDB JSON。動作可橫跨表格(同一帳戶 + Region),但沒有兩個動作可鎖定同一個項目 — 光是這樣就會取消交易。ConditionCheck— 對交易不修改的項目斷言一個條件(例如「帳戶仍存在」),若失敗則否決整個交易。TransactionCanceledException— 唯一需要處理的錯誤。e.response["CancellationReasons"]依序列出每個動作的一個{"Code", "Message"}— code 包括ConditionalCheckFailed、TransactionConflict(另一個交易在過程中觸及某個項目 — 以退避安全重試)、ProvisionedThroughputExceeded與ValidationError;None標記無辜的動作。在某個動作上設定"ReturnValuesOnConditionCheckFailure": "ALL_OLD",可在其原因中取得敗方項目的屬性。ClientRequestToken— 傳入一個 token 讓呼叫在 10 分鐘內具冪等性;網路逾時後的 botocore 重試也無法把寫入套用兩次。- 成本 — 交易式寫入每個項目消耗兩個底層寫入(準備 + 提交),因此計費約為一般寫入 WCU 的 2×。當單一項目的 條件式寫入 已能給你單一項目的 atomic 性時,別動用交易。
改用視覺化操作
每個動作裡的條件與 update 運算式是繁瑣的部分 — DynamoDB Expression Builder 會連同 name/value map 一起組裝它們並複製可執行的 boto3 程式碼。
想在 GUI 中編輯項目並審視產生的運算式 — 下載 DynoTable。
相關範例
- 在 Node.js 中使用 DynamoDB TransactWriteItems — 以 AWS SDK v3 執行相同的交易。
- 使用 AWS CLI 執行 DynamoDB TransactWriteItems — 從 shell 執行相同的交易。
- 在 Python 中執行 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
- DynamoDB.Client.transact_write_items — Boto3 documentation
- 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 官方文件。