在 Python(boto3)中使用 DynamoDB TransactWriteItems

transact_write_items 把多達 100 個寫入組成一個全有或全無的操作 — 要嘛每個動作都提交,要嘛都不。使用 boto3 低階 client 時,你傳入一個混合 PutUpdateDeleteConditionCheck 動作的 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 包括 ConditionalCheckFailedTransactionConflict(另一個交易在過程中觸及某個項目 — 以退避安全重試)、ProvisionedThroughputExceededValidationErrorNone 標記無辜的動作。在某個動作上設定 "ReturnValuesOnConditionCheckFailure": "ALL_OLD",可在其原因中取得敗方項目的屬性。
  • ClientRequestToken — 傳入一個 token 讓呼叫在 10 分鐘內具冪等性;網路逾時後的 botocore 重試也無法把寫入套用兩次。
  • 成本 — 交易式寫入每個項目消耗兩個底層寫入(準備 + 提交),因此計費約為一般寫入 WCU 的 2×。當單一項目的 條件式寫入 已能給你單一項目的 atomic 性時,別動用交易。

改用視覺化操作

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

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

相關範例

References

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

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

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