Python(boto3)中的 DynamoDB TransactWriteItems

transact_write_items 把多达 100 次写入组成一次全有或全无的操作——要么每个动作都提交,要么一个都不提交。使用 boto3 低级 client,你传入一个混合了 PutUpdateDeleteConditionCheck 动作的 TransactItems 列表,每个都可带一个可选条件。

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。动作可以跨表(同一账户 + 区域),但任意两个动作都不可针对同一个项目——仅此一条就会取消事务。
  • ConditionCheck — 对事务修改的某个项目断言一个条件(例如"该账户仍然存在"),若失败则否决整个事务。
  • TransactionCanceledException — 唯一需要处理的错误。e.response["CancellationReasons"] 按顺序为每个动作列出一个 {"Code", "Message"}——代码包括 ConditionalCheckFailedTransactionConflict(另一个事务在中途触及了某个项目——可用退避安全重试)、ProvisionedThroughputExceededValidationErrorNone 标记无辜的动作。在某个动作上设置 "ReturnValuesOnConditionCheckFailure": "ALL_OLD" 可在其原因中获得失败项目的属性。
  • ClientRequestToken — 传入一个可让调用在 10 分钟内保持幂等;网络超时后的 botocore 重试便不会把写入应用两次。
  • 成本 — 事务写入每个项目消耗两次底层写入(准备 + 提交),因此计费大约是普通写入 WCU 的 2 倍。当一次单项条件写入已能为单个项目提供原子性时,不要动用事务。

可视化操作

每个动作内部的条件和更新表达式才是繁琐之处——DynamoDB Expression Builder 会连同名称/值映射一起组装它们,并复制可运行的 boto3 代码。

想在 GUI 中编辑项目并审阅生成的表达式——请下载 DynoTable

相关示例

References

Last verified 2026-07-13 against the official AWS documentation linked above.

无需控制台即可使用 DynamoDB

DynoTable 是面向 DynamoDB 的快速桌面客户端 —— 浏览表、运行 SQL 风格的查询,并在本地编辑项。