DynamoDB TransactWriteItems en Python (boto3)

transact_write_items agrupa hasta 100 escrituras en una operación de todo o nada — o se aplican todas las acciones, o ninguna. Con el cliente de bajo nivel de boto3 pasas una lista TransactItems que mezcla acciones Put, Update, Delete y ConditionCheck, cada una con una condición 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']

Explicación

  • TransactItems — hasta 100 acciones Put / Update / Delete / ConditionCheck, 4 MB agregados, valores en DynamoDB JSON. Las acciones pueden abarcar tablas (misma cuenta + Región), pero dos acciones no pueden apuntar al mismo item — eso por sí solo cancela la transacción.
  • ConditionCheck — afirma una condición sobre un item que la transacción no modifica (p. ej. "la cuenta aún existe") y veta toda la transacción si falla.
  • TransactionCanceledException — el único error que manejar. e.response["CancellationReasons"] lista un {"Code", "Message"} por acción en orden — los códigos incluyen ConditionalCheckFailed, TransactionConflict (otra transacción tocó un item a mitad de vuelo — seguro de reintentar con retroceso), ProvisionedThroughputExceeded y ValidationError; None marca las acciones inocentes. Pon "ReturnValuesOnConditionCheckFailure": "ALL_OLD" en una acción para obtener los atributos del item perdedor en su motivo.
  • ClientRequestToken — pasa uno para hacer la llamada idempotente durante 10 minutos; un reintento de botocore tras un timeout de red no puede entonces aplicar las escrituras dos veces.
  • Coste — las escrituras transaccionales consumen dos escrituras subyacentes por item (preparar + confirmar), así que facturan aproximadamente 2× las WCU de una escritura simple. No recurras a las transacciones cuando una escritura condicional sobre un solo item ya te da atomicidad sobre un item.

Hazlo visualmente

Las expresiones de condición y de actualización dentro de cada acción son la parte delicada — el DynamoDB Expression Builder las ensambla con los mapas de nombre/valor y copia código boto3 ejecutable.

Para editar items y revisar las expresiones generadas en una interfaz gráfica — descarga DynoTable.

Ejemplos relacionados

References

Verificado por última vez el 2026-07-13 contra la documentación oficial de AWS enlazada arriba.

Trabaja con DynamoDB sin la Consola

DynoTable es un cliente de escritorio rápido para DynamoDB: explora tablas, ejecuta consultas estilo SQL y edita Items localmente.