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 ClientRequestToken gleichzeitig ausgeben.

So behebst du es

  1. 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.

  2. 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.
  3. Rotiere den Token beim Retry nicht — einen frischen ClientRequestToken pro 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}));
  4. 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

Referenzen

Zuletzt verifiziert am 2026-07-13 gegen die oben verlinkte offizielle AWS-Dokumentation.

Mit DynamoDB ohne die Console arbeiten

DynoTable ist ein schneller Desktop-Client für DynamoDB — durchsuche Tabellen, führe SQL-artige Queries aus und bearbeite Items lokal.