TransactionInProgressException
TL;DR — Un retry de TransactWriteItems a porté le même ClientRequestToken qu'une tentative qui est encore en cours d'exécution. C'est généralement ton client qui expire plus vite que la transaction ne se termine, donc le retry du SDK entre en collision avec l'original en cours. Continue de réessayer avec backoff — un retry ultérieur, une fois l'original terminé, renvoie le succès idempotent — et règle les timeouts pour qu'au moins un retry atterrisse après ~5 secondes.
Ce que ça signifie
TransactionInProgressException: The transaction with the given request token
is already in progress.ClientRequestToken rend TransactWriteItems idempotent : des appels identiques dans une fenêtre de 10 minutes comptent comme une seule transaction. Tant que la première tentative est encore en cours de traitement, un deuxième appel avec le même token ne peut pas encore recevoir de réponse — ce n'est ni un doublon d'une transaction terminée ni une nouvelle — donc DynamoDB le rejette avec cette exception. C'est un signal de timing, pas une erreur de données.
Pourquoi ça arrive
- Timeout client plus court que la latence de la transaction — le timeout de requête se déclenche, le SDK réessaie, et le retry arrive alors que la transaction originale est encore en train de commiter.
- Politique de retry agressive — un backoff très court signifie que plusieurs retries peuvent s'empiler sur une transaction qui a besoin de quelques secondes.
- Deux appelants partageant un token — des processus séparés émettant délibérément (ou accidentellement) le même
ClientRequestTokende façon concurrente.
Comment le corriger
Laisse les retries continuer avec un backoff exponentiel — une fois la transaction en cours terminée, un retry avec le même token renvoie un succès sans appliquer les écritures deux fois. Traite cette exception comme réessayable.
Règle les timeouts selon les recommandations documentées pour qu'un retry puisse atterrir après le règlement de la transaction :
- autorise au moins un retry à être traité après que 5 secondes se sont écoulées depuis la première tentative ;
- fixe le timeout par requête à environ 1 seconde ou plus ;
- garde le timeout de socket légèrement en dessous du timeout de requête ;
- utilise un backoff exponentiel entre les tentatives.
Ne fais pas tourner le token à chaque retry — générer un nouveau
ClientRequestTokenpar tentative convertit silencieusement les retries en nouvelles transactions (double application des écritures). Même intention, même token, pendant jusqu'à 10 minutes :const token = randomUUID(); // one token per logical transaction await client.send(new TransactWriteItemsCommand({TransactItems, ClientRequestToken: token}));Sérialise les appelants concurrents délibérés — si deux workers peuvent soumettre la même transaction logique, désigne l'un comme propriétaire ou fais passer les deux par une file d'attente.
Si les transactions durent assez longtemps pour dépasser les timeouts, vérifie sur quoi elles sont en contention — l'application de bureau DynoTable te laisse inspecter les éléments impliqués, et le calculateur de prix DynamoDB montre ce que coûte la capacité d'écriture doublée des écritures transactionnelles.
Erreurs liées
- IdempotentParameterMismatchException — même token, payload différent.
- TransactionCanceledException — la transaction elle-même a échoué.
- TransactionConflictException — conflit au niveau élément avec une autre transaction.
- Exemple de code : TransactWriteItems en Node.js — montre l'usage de ClientRequestToken.
- En savoir plus : Transactions DynamoDB
Références
- TransactWriteItems — Amazon DynamoDB API Reference
- Amazon DynamoDB Transactions: How it works — Amazon DynamoDB Developer Guide
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
Dernière vérification le 2026-07-13 par rapport à la documentation officielle AWS liée ci-dessus.