DynamoDB TransactionCanceledException

TL;DR — Satu (atau lebih) item dalam TransactWriteItems / TransactGetItems Anda gagal, jadi DynamoDB me-rollback seluruh transaksi. Penyebab sebenarnya ada di array CancellationReasons — bacalah; Code alasan per item memberi tahu persis item mana dan mengapa.

Apa artinya

Transaksi DynamoDB bersifat semua-atau-tidak-sama-sekali. Kalau kondisi salah satu item gagal, kapasitas terlampaui, atau dua transaksi bertabrakan, semuanya dibatalkan dan tidak ada yang ditulis. Pesan di tingkat atas bersifat umum:

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

Daftar dalam kurung siku itu bersifat posisional — satu entri per item dalam transaksi Anda, sesuai urutan. DynamoDB mengembalikan exception ini dengan status HTTP 400, dan AWS SDK tidak mencobanya ulang secara otomatis — kode Anda yang memutuskan, per kode alasan, apakah percobaan ulang masuk akal.

Mengapa terjadi (kode alasan)

  • ConditionalCheckFailedConditionExpression item itu bernilai false (lihat ConditionalCheckFailedException).
  • TransactionConflict — transaksi (atau penulisan) lain yang bersamaan sedang bekerja pada item yang sama; coba ulang dengan backoff.
  • ProvisionedThroughputExceeded — tabel/index item itu kehabisan kapasitas.
  • ThrottlingError — tabel atau index (biasanya on-demand, saat DynamoDB masih menskalakannya) men-throttle penulisan itu; coba ulang dengan backoff.
  • ValidationError — item itu cacat bentuk (nilai parameter tidak valid, document path, tipe operand, ukuran berlebih, …).
  • ItemCollectionSizeLimitExceeded — sebuah item collection LSI menyentuh 10 GB.
  • None — item itu baik-baik saja; kegagalannya ada di tempat lain dalam daftar.

Itulah himpunan kode yang terdokumentasi selengkapnya. Perhatikan bahwa key item yang duplikat (item yang sama disasar dua aksi) bukan kode pembatalan — DynamoDB menolak request semacam itu di awal sebagai ValidationException.

Bagaimana cara memperbaikinya

  1. Baca CancellationReasons dari error-nya, bukan hanya pesannya. Petakan setiap entri kembali ke item input Anda berdasarkan indeks.
  2. Bercabanglah berdasarkan kode: ConditionalCheckFailed → logika bisnis; TransactionConflict/ThrottlingError/ProvisionedThroughputExceeded → coba ulang dengan exponential backoff; ValidationError → betulkan request-nya.
  3. Hindari key duplikat — satu transaksi tidak bisa menyentuh item yang sama dua kali.

Menyunting item secara manual? Staging area DynoTable mengumpulkan suntingan Anda menjadi satu penulisan transaksional dan membiarkan Anda meninjau setiap item sebelum Commit — semantik semua-atau-tidak-sama-sekali yang sama tanpa perlu menyusun request dengan tangan.

Contoh

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

Mengapa transaksi DynamoDB saya dibatalkan? Satu item dalam TransactWriteItems/TransactGetItems gagal — pemeriksaan kondisi, batas throughput/throttling, atau konflik dengan transaksi lain yang bersamaan — sehingga DynamoDB me-rollback seluruh transaksi dan tidak menulis apa pun. Alasan per item ada di array CancellationReasons.

Bagaimana cara mengetahui item mana dalam transaksi yang gagal? Baca array CancellationReasons pada TransactionCanceledException. Ia berisi satu entri per item input, dalam urutan yang sama; entri yang Code-nya bukan "None" adalah item yang menyebabkan pembatalan.

Cara mereproduksinya

Dua penulisan dalam satu transaksi, yang kedua dijaga oleh kondisi yang mustahil terpenuhi. Seluruh transaksi di-rollback, dan vonis per aksi datang di CancellationReasons — sejajar secara posisional dengan 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
        }
      }
    ]
  })
);

Keluaran sebenarnya:

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

Aksi pertama melaporkan None — ia tidak gagal, ia di-rollback karena tetangganya yang gagal. Hanya entri yang Code-nya bukan None yang menunjukkan biang keladi sesungguhnya, dan indeksnya adalah indeks aksi bermasalah di dalam array TransactItems Anda sendiri.

Kesalahan terkait

Referensi

Terakhir diverifikasi 2026-07-13 terhadap dokumentasi resmi AWS yang ditautkan di atas.

Direproduksi 2026-07-26 terhadap DynamoDB Local 2.x dengan AWS SDK for JavaScript v3.1095.0 — keluaran di atas dikutip apa adanya.

Bekerja dengan DynamoDB tanpa Console

Klien desktop DynamoDB yang cepat dan menjalankan SQL sungguhan yang tidak bisa dijalankan DynamoDB — JOINs, GROUP BY, agregasi — dengan editing visual dan agen AI pada kunci Bedrock milik Anda sendiri.

Uji coba gratis 30 hari, tanpa kartu kredit — lalu paket Free tanpa batas waktu.