TransactWriteItems DynamoDB en Python (boto3)

transact_write_items regroupe jusqu'à 100 écritures en une seule opération tout-ou-rien — soit chaque action est validée, soit aucune ne l'est. Avec le client bas niveau boto3, tu passes une liste TransactItems mêlant des actions Put, Update, Delete et ConditionCheck, chacune avec une condition optionnelle.

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

Explication

  • TransactItems — jusqu'à 100 actions Put / Update / Delete / ConditionCheck, 4 Mo au total, valeurs en DynamoDB JSON. Les actions peuvent s'étendre sur plusieurs tables (même compte + même Region), mais deux actions ne peuvent pas cibler le même élément — cela seul annule la transaction.
  • ConditionCheck — affirme une condition sur un élément que la transaction ne modifie pas (par ex. « le compte existe toujours ») et met son veto sur toute la transaction si elle échoue.
  • TransactionCanceledException — la seule erreur à gérer. e.response["CancellationReasons"] liste un {"Code", "Message"} par action dans l'ordre — les codes incluent ConditionalCheckFailed, TransactionConflict (une autre transaction a touché un élément en cours de route — sûr à réessayer avec backoff), ProvisionedThroughputExceeded et ValidationError ; None marque les actions innocentes. Fixe "ReturnValuesOnConditionCheckFailure": "ALL_OLD" sur une action pour obtenir les attributs de l'élément perdant dans sa raison.
  • ClientRequestToken — passes-en un pour rendre l'appel idempotent pendant 10 minutes ; une réexécution de botocore après un timeout réseau ne peut alors pas appliquer les écritures deux fois.
  • Coût — les écritures transactionnelles consomment deux écritures sous-jacentes par élément (préparation + validation), donc elles facturent environ 2× les WCU d'une écriture simple. Ne te tourne pas vers les transactions quand une écriture conditionnelle sur un seul élément te donne déjà l'atomicité sur cet élément.

À faire visuellement

Les expressions de condition et de mise à jour à l'intérieur de chaque action sont la partie délicate — le DynamoDB Expression Builder les assemble avec les maps de noms/valeurs et copie du code boto3 exécutable.

Pour éditer des éléments et examiner les expressions générées dans une interface graphique — télécharge DynoTable.

Exemples liés

References

Dernière vérification le 2026-07-13 par rapport à la documentation officielle AWS liée ci-dessus.

Travaille avec DynamoDB sans la Console

DynoTable est un client de bureau rapide pour DynamoDB — parcours les tables, exécute des requêtes de style SQL et édite les items en local.