DynamoDB TransactionCanceledException

TL;DR — Ein (oder mehrere) Items in deinem TransactWriteItems / TransactGetItems sind fehlgeschlagen, sodass DynamoDB die gesamte Transaktion zurückgerollt hat. Die eigentliche Ursache steht im CancellationReasons-Array — lies es; der Reason-Code pro Item sagt dir genau, welches Item und warum.

Was es bedeutet

DynamoDB-Transaktionen sind Alles-oder-Nichts. Wenn die Bedingung eines Items fehlschlägt, die Kapazität überschritten wird oder zwei Transaktionen kollidieren, wird das Ganze abgebrochen und nichts wird geschrieben. Die Top-Level-Meldung ist generisch:

TransactionCanceledException: Transaction cancelled, please refer cancellation reasons for specific reasons [ConditionalCheckFailed, None, TransactionConflict]

Die eingeklammerte Liste ist positional — ein Eintrag pro Item in deiner Transaktion, in Reihenfolge. DynamoDB gibt diese Exception mit HTTP-Status 400 zurück, und die AWS-SDKs wiederholen sie nicht automatisch — dein Code entscheidet pro Reason-Code, ob ein Retry sinnvoll ist.

Warum es passiert (die Reason-Codes)

  • ConditionalCheckFailed — die ConditionExpression dieses Items wurde zu false ausgewertet (siehe ConditionalCheckFailedException).
  • TransactionConflict — eine andere gleichzeitige Transaktion (oder ein Write) operiert auf demselben Item; wiederhole mit Backoff.
  • ProvisionedThroughputExceeded — der Tabelle/dem Index des Items ist die Kapazität ausgegangen.
  • ThrottlingError — die Tabelle oder der Index (typischerweise On-Demand, während DynamoDB sie noch skaliert) hat den Write gedrosselt; wiederhole mit Backoff.
  • ValidationError — dieses Item war fehlerhaft (ungültige Parameterwerte, Dokumentpfad, Operand-Typ, Größenüberschreitung, …).
  • ItemCollectionSizeLimitExceeded — eine LSI-Item-Collection hat 10 GB erreicht.
  • None — dieses Item war in Ordnung; der Fehler lag anderswo in der Liste.

Das ist der vollständige dokumentierte Code-Satz. Beachte, dass ein doppelter Item-Schlüssel (dasselbe Item, von zwei Aktionen adressiert) kein Cancellation-Code ist — DynamoDB weist diesen Request stattdessen von vornherein als ValidationException zurück.

So behebst du es

  1. Lies CancellationReasons aus dem Fehler, nicht nur die Meldung. Ordne jeden Eintrag über den Index zu deinem Input-Item zurück.
  2. Verzweige nach Code: ConditionalCheckFailed → Business-Logik; TransactionConflict/ThrottlingError/ProvisionedThroughputExceeded → mit exponentiellem Backoff wiederholen; ValidationError → den Request korrigieren.
  3. Vermeide doppelte Schlüssel — eine einzelne Transaktion kann dasselbe Item nicht zweimal berühren.

Bearbeitest du Items von Hand? DynoTables Staging-Bereich bündelt deine Änderungen in einen einzigen transaktionalen Write und lässt dich jedes Item vor dem Committen prüfen — dieselbe Alles-oder-nichts-Semantik, ohne den Request von Hand zu bauen.

Beispiel

import {DynamoDBClient, TransactionCanceledException} from '@aws-sdk/client-dynamodb';
import {DynamoDBDocumentClient, TransactWriteCommand} from '@aws-sdk/lib-dynamodb';

const doc = DynamoDBDocumentClient.from(new DynamoDBClient({}));

try {
  await doc.send(new TransactWriteCommand({TransactItems: [/* ... */]}));
} catch (err) {
  if (err instanceof TransactionCanceledException) {
    for (const [i, reason] of (err.CancellationReasons ?? []).entries()) {
      if (reason.Code && reason.Code !== 'None') {
        console.error(`item ${i} cancelled: ${reason.Code}${reason.Message}`);
      }
    }
  }
  throw err;
}

FAQ

Warum wurde meine DynamoDB-Transaktion abgebrochen? Ein Item in den TransactWriteItems/TransactGetItems ist fehlgeschlagen — ein Condition-Check, ein Durchsatz-/Throttling-Limit oder ein Konflikt mit einer anderen gleichzeitigen Transaktion — sodass DynamoDB die ganze Transaktion zurückgerollt und nichts geschrieben hat. Der Grund pro Item steht im CancellationReasons-Array.

Wie finde ich heraus, welches Item in der Transaktion fehlgeschlagen ist? Lies das CancellationReasons-Array der TransactionCanceledException. Es hat einen Eintrag pro Input-Item, in derselben Reihenfolge; der Eintrag, dessen Code nicht "None" ist, ist das Item, das den Abbruch verursacht hat.

So reproduzierst du es

Zwei Writes in einer Transaktion, der zweite abgesichert durch eine Bedingung, die nicht halten kann. Die gesamte Transaktion wird zurückgerollt, und die Urteile pro Aktion kommen in CancellationReasons an — positionsgenau ausgerichtet an TransactItems:

await client.send(
  new TransactWriteItemsCommand({
    TransactItems: [
      {Put: {TableName: 'orders', Item: {pk: {S: 'OK'}, sk: {S: 'META'}}}},
      {
        Put: {
          TableName: 'orders',
          Item: {pk: {S: 'ORDER#1'}, sk: {S: 'META'}},
          ConditionExpression: 'attribute_not_exists(pk)' // ORDER#1 already exists
        }
      }
    ]
  })
);

Echte Ausgabe:

TransactionCanceledException: Transaction cancelled, please refer cancellation reasons for specific reasons [None, ConditionalCheckFailed]
HTTP 400

error.CancellationReasons:
[
  {
    "Code": "None"
  },
  {
    "Code": "ConditionalCheckFailed",
    "Message": "The conditional request failed"
  }
]

Die erste Aktion meldet None — sie ist nicht fehlgeschlagen, sie wurde zurückgerollt, weil ihre Nachbarin es war. Nur der Eintrag, dessen Code nicht None ist, benennt die tatsächliche Ursache, und sein Index ist der Index der störenden Aktion in deinem eigenen TransactItems-Array.

Verwandte Fehler

Referenzen

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

Am 2026-07-26 gegen DynamoDB Local 2.x mit dem AWS SDK for JavaScript v3.1095.0 reproduziert — die Ausgabe oben ist wortgetreu.

Mit DynamoDB ohne die Console arbeiten

Ein schneller DynamoDB-Desktop-Client, der das echte SQL ausführt, das DynamoDB nicht kann — JOINs, GROUP BY, Aggregationen — mit visueller Bearbeitung und einem KI-Agenten auf deinen eigenen Bedrock-Schlüsseln.

30 Tage kostenlos testen, keine Kreditkarte — danach der Kostenlos-Tarif ohne Zeitlimit.