DynamoDB TransactionCanceledException — ConditionalCheckFailed

En bref — Ton TransactWriteItems a été annulé et le tableau CancellationReasons contient une entrée ConditionalCheckFailed. L'une des expressions de condition de la transaction n'a pas tenu, donc DynamoDB a annulé chaque action de façon atomique. Lis le tableau des raisons — ses entrées sont positionnelles, une par élément demandé — pour trouver quel élément a échoué sa condition, puis corrige la précondition de cet élément ou les données.

Ce que ça signifie

TransactionCanceledException: Transaction cancelled, please refer cancellation
reasons for specific reasons [ConditionalCheckFailed, None, None]
# CancellationReasons[0] = { Code: "ConditionalCheckFailed",
#                            Message: "The conditional request failed" }

TransactWriteItems est du tout-ou-rien. Si le ConditionExpression d'une seule action s'évalue à faux, DynamoDB annule toute la requête et renvoie une liste de raisons par élément. ConditionalCheckFailed à la position i signifie que la condition du i-ème élément n'a pas été satisfaite — la transaction ne s'est jamais appliquée partiellement.

Pourquoi ça arrive

  • Échec de verrou optimiste — un garde version = :v / attribute_not_exists(pk) a échoué parce qu'un autre écrivain a déjà modifié ou créé l'élément.
  • Garde d'unicité déclenchée — un insert attribute_not_exists(pk) a perdu une course, donc l'élément existe déjà.
  • Lecture périmée — la condition a été construite à partir d'une valeur qui a changé depuis.
  • Liste de raisons mal lue — le tableau est positionnel, ordonné comme tes TransactItems ; un None à un emplacement signifie que cet élément allait bien, ConditionalCheckFailed marque celui qui a échoué. (D'autres codes dans le tableau — TransactionConflict, ItemCollectionSizeLimitExceeded, ProvisionedThroughputExceeded, ThrottlingError, ValidationError — signifient autre chose.)

Comment corriger

  1. Inspecte CancellationReasons dans l'exception et trouve l'index avec ConditionalCheckFailed — c'est l'action en échec.
  2. Relis l'élément et décide : réessaie avec une précondition fraîche (boucle de réessai à verrou optimiste) ou remonte un conflit à l'appelant.
  3. Corrige la condition si elle est fausse — p. ex. attribute_not_exists(pk) sur un élément qui existe légitimement déjà.
  4. Ajoute ReturnValuesOnConditionCheckFailure: ALL_OLD à l'action en échec pour que DynamoDB renvoie l'élément qui a brisé la condition (idéal pour le débogage).
  5. Borne tes réessais — une condition qui échoue systématiquement est un vrai conflit métier, pas une erreur transitoire ; ne réessaie pas à l'infini.

Tu débogues une transaction en échec à la main ? Inspecte l'état actuel de l'élément dans l'application de bureau DynoTable pour voir exactement pourquoi la précondition n'a pas tenu avant de réessayer.

FAQ

Comment savoir quel élément de ma transaction a échoué ? Lis le tableau CancellationReasons sur la TransactionCanceledException. Il est positionnel — une entrée par élément demandé, dans l'ordre. L'entrée avec le code ConditionalCheckFailed identifie l'action dont l'expression de condition s'est évaluée à faux ; les entrées avec le code None ont réussi.

Un ConditionalCheckFailed à l'intérieur d'une transaction est-il réessayable ? Pas automatiquement. C'est un vrai conflit de précondition, pas une erreur transitoire. Relis l'élément, décide si l'écriture s'applique encore, et réessaie avec une condition fraîche — ou remonte le conflit à l'utilisateur.

Erreurs liées

Références

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.