DynamoDB TransactWriteItems em Python (boto3)

transact_write_items agrupa até 100 gravações em uma única operação tudo-ou-nada — ou toda ação é confirmada, ou nenhuma é. Com o client de baixo nível do boto3 você passa uma lista TransactItems misturando ações Put, Update, Delete e ConditionCheck, cada uma com uma condição opcional.

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']

Explicação

  • TransactItems — até 100 ações Put / Update / Delete / ConditionCheck, 4 MB agregados, valores em DynamoDB JSON. As ações podem abranger tabelas (mesma conta + Region), mas nenhuma dupla de ações pode mirar o mesmo item — isso sozinho cancela a transação.
  • ConditionCheck — afirma uma condição sobre um item que a transação não modifica (por exemplo, "a conta ainda existe") e veta a transação inteira se ela falhar.
  • TransactionCanceledException — o único erro a tratar. e.response["CancellationReasons"] lista um {"Code", "Message"} por ação em ordem — os códigos incluem ConditionalCheckFailed, TransactionConflict (outra transação tocou um item no meio do caminho — seguro para retry com backoff), ProvisionedThroughputExceeded e ValidationError; None marca as ações inocentes. Defina "ReturnValuesOnConditionCheckFailure": "ALL_OLD" em uma ação para obter os atributos do item perdedor na sua razão.
  • ClientRequestToken — passe um para tornar a chamada idempotente por 10 minutos; um retry do botocore após um timeout de rede então não pode aplicar as gravações duas vezes.
  • Custo — gravações transacionais consomem duas gravações subjacentes por item (preparar + confirmar), então cobram aproximadamente 2× as WCUs de uma gravação simples. Não recorra a transações quando uma gravação condicional de item único já lhe dá atomicidade em um item.

Faça visualmente

As condition e update expressions dentro de cada ação são a parte chata — o DynamoDB Expression Builder as monta com os mapas de nome/valor e copia código boto3 executável.

Para editar itens e revisar as expressões geradas numa GUI — baixe o DynoTable.

Exemplos relacionados

References

Última verificação em 2026-07-13 contra a documentação oficial da AWS vinculada acima.

Trabalhe com o DynamoDB sem o Console

O DynoTable é um cliente desktop rápido para o DynamoDB — navegue pelas tabelas, execute consultas no estilo SQL e edite itens localmente.