TransactionInProgressException
TL;DR — Ein TransactWriteItems-Retry trug denselben ClientRequestToken wie ein Versuch, der noch ausgeführt wird. Das ist meist dein Client, der schneller ein Timeout auslöst, als die Transaktion abschließt, sodass der Retry des SDK mit dem laufenden Original kollidiert. Wiederhole weiter mit Backoff — ein späterer Retry, nachdem das Original fertig ist, gibt den idempotenten Erfolg zurück — und tune Timeouts so, dass mindestens ein Retry nach ~5 Sekunden landet.
Was es bedeutet
TransactionInProgressException: The transaction with the given request token
is already in progress.ClientRequestToken macht TransactWriteItems idempotent: identische Aufrufe innerhalb eines 10-Minuten-Fensters zählen als eine Transaktion. Während der erste Versuch noch verarbeitet wird, kann ein zweiter Aufruf mit demselben Token noch nicht beantwortet werden — er ist weder ein Duplikat einer abgeschlossenen Transaktion noch eine neue — also lehnt DynamoDB ihn mit dieser Exception ab. Es ist ein Timing-Signal, kein Datenfehler.
Warum es passiert
- Client-Timeout kürzer als die Transaktionslatenz — das Request-Timeout feuert, das SDK wiederholt, und der Retry kommt an, während die Original-Transaktion noch committet.
- Aggressive Retry-Policy — sehr kurzer Backoff bedeutet, dass sich mehrere Retries auf eine Transaktion häufen können, die ein paar Sekunden braucht.
- Zwei Aufrufer teilen sich einen Token — separate Prozesse, die absichtlich (oder versehentlich) denselben
ClientRequestTokengleichzeitig ausgeben.
So behebst du es
Lass die Retries mit exponentiellem Backoff weiterlaufen — sobald die laufende Transaktion abschließt, gibt ein Retry mit demselben Token Erfolg zurück, ohne die Writes doppelt anzuwenden. Behandle diese Exception als wiederholbar.
Tune Timeouts gemäß der dokumentierten Empfehlung, sodass ein Retry landen kann, nachdem sich die Transaktion beruhigt hat:
- lass mindestens einen Retry verarbeiten, nachdem 5 Sekunden verstrichen sind, seit dem ersten Versuch;
- setze das Per-Request-Timeout auf etwa 1 Sekunde oder höher;
- halte das Socket-Timeout etwas unter dem Request-Timeout;
- nutze exponentiellen Backoff zwischen den Versuchen.
Rotiere den Token beim Retry nicht — einen frischen
ClientRequestTokenpro Versuch zu generieren, verwandelt Retries stillschweigend in neue Transaktionen (die Writes doppelt anwenden). Gleiche Absicht, gleicher Token, für bis zu 10 Minuten:const token = randomUUID(); // one token per logical transaction await client.send(new TransactWriteItemsCommand({TransactItems, ClientRequestToken: token}));Serialisiere absichtliche gleichzeitige Aufrufer — wenn zwei Worker dieselbe logische Transaktion einreichen können, mache einen zum Owner oder leite beide durch eine Queue.
Wenn Transaktionen lange genug laufen, um Timeouts auszulösen, prüfe, worum sie konkurrieren — die DynoTable-Desktop-App lässt dich die beteiligten Items inspizieren, und der DynamoDB-Preisrechner zeigt, was die verdoppelte Write-Kapazität transaktionaler Writes kostet.
Verwandte Fehler
- IdempotentParameterMismatchException — gleicher Token, anderes Payload.
- TransactionCanceledException — die Transaktion selbst ist fehlgeschlagen.
- TransactionConflictException — Konflikt auf Item-Ebene mit einer anderen Transaktion.
- Code-Beispiel: TransactWriteItems in Node.js — zeigt die Verwendung von ClientRequestToken.
- Learn: DynamoDB-Transaktionen
Referenzen
- TransactWriteItems — Amazon DynamoDB API Reference
- Amazon DynamoDB Transactions: How it works — Amazon DynamoDB Developer Guide
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
Zuletzt verifiziert am 2026-07-13 gegen die oben verlinkte offizielle AWS-Dokumentation.