DynamoDB TransactionCanceledException

In breve — Uno (o più) Item nel tuo TransactWriteItems / TransactGetItems è fallito, quindi DynamoDB ha fatto il rollback dell'intera transazione. La vera causa è nell'array CancellationReasons — leggilo; il Code della ragione per Item ti dice esattamente quale Item e perché.

Cosa significa

Le transazioni DynamoDB sono tutto-o-niente. Se la condizione di un Item fallisce, la capacità viene superata, o due transazioni collidono, l'intera cosa viene annullata e nulla viene scritto. Il messaggio di livello superiore è generico:

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

L'elenco tra parentesi è posizionale — una voce per Item nella tua transazione, in ordine. DynamoDB restituisce questa eccezione con stato HTTP 400, e gli AWS SDK non la riprovano automaticamente — il tuo codice decide, per ogni codice di ragione, se un retry ha senso.

Perché accade (i codici di ragione)

  • ConditionalCheckFailed — il ConditionExpression di quell'Item è risultato falso (vedi ConditionalCheckFailedException).
  • TransactionConflict — un'altra transazione concorrente (o scrittura) sta operando sullo stesso Item; riprova con backoff.
  • ProvisionedThroughputExceeded — la tabella/indice dell'Item ha esaurito la capacità.
  • ThrottlingError — la tabella o l'indice (tipicamente on-demand, mentre DynamoDB la sta ancora scalando) ha fatto throttling sulla scrittura; riprova con backoff.
  • ValidationError — quell'Item era malformato (valori di parametro non validi, document path, tipo di operando, overflow di dimensione, …).
  • ItemCollectionSizeLimitExceeded — una item collection LSI ha raggiunto i 10 GB.
  • None — quell'Item era a posto; il fallimento era altrove nell'elenco.

Questo è l'insieme completo di codici documentato. Nota che una chiave di Item duplicata (lo stesso Item puntato da due azioni) non è un codice di annullamento — DynamoDB rifiuta quella richiesta subito come ValidationException.

Come risolverlo

  1. Leggi CancellationReasons dall'errore, non solo il messaggio. Mappa ogni voce al tuo Item di input tramite l'indice.
  2. Ramifica per codice: ConditionalCheckFailed → logica di business; TransactionConflict/ThrottlingError/ProvisionedThroughputExceeded → riprova con backoff esponenziale; ValidationError → correggi la richiesta.
  3. Evita chiavi duplicate — una singola transazione non può toccare lo stesso Item due volte.

Modifichi gli item a mano? L'area di staging di DynoTable raggruppa le tue modifiche in un'unica scrittura transazionale e ti lascia rivedere ogni Item prima del commit — la stessa semantica tutto-o-niente senza costruire la richiesta a mano.

Esempio

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

Perché la mia transazione DynamoDB è stata annullata? Un Item nel TransactWriteItems/TransactGetItems è fallito — un controllo di condizione, un limite di throughput/throttling, o un conflitto con un'altra transazione concorrente — quindi DynamoDB ha fatto il rollback dell'intera transazione e non ha scritto nulla. La ragione per-Item è nell'array CancellationReasons.

Come trovo quale Item della transazione è fallito? Leggi l'array CancellationReasons sulla TransactionCanceledException. Ha una voce per Item di input, nello stesso ordine; la voce il cui Code non è "None" è l'Item che ha causato l'annullamento.

Riproducilo

Due scritture in un'unica transazione, la seconda protetta da una condizione che non può essere soddisfatta. L'intera transazione va in rollback, e i verdetti per azione arrivano in CancellationReasons — allineati posizionalmente con 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
        }
      }
    ]
  })
);

Output reale:

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"
  }
]

La prima azione riporta None — non è fallita, ha subito il rollback perché è fallita quella accanto. Solo la voce il cui Code non è None identifica il vero colpevole, e il suo indice è l'indice dell'azione problematica nel tuo array TransactItems.

Errori correlati

Riferimenti

Ultima verifica 2026-07-13 rispetto alla documentazione ufficiale AWS collegata sopra.

Riprodotto il 2026-07-26 su DynamoDB Local 2.x con AWS SDK for JavaScript v3.1095.0 — l'output qui sopra è riportato alla lettera.

Lavora con DynamoDB senza la Console

Un client desktop veloce per DynamoDB che esegue il vero SQL che DynamoDB non può — JOINs, GROUP BY, aggregazioni — con modifica visuale e un agente AI sulle tue chiavi Bedrock.

Prova gratuita di 30 giorni, senza carta di credito — poi il piano Free senza limiti di tempo.