DynamoDB TransactWriteItems di Node.js (AWS SDK v3)
TransactWriteItemsCommand yang berhasil nyaris tidak memberi tahu apa pun: tanpa item, tanpa atribut, responsnya kosong. Segala yang Anda butuhkan ada di exception-nya, jadi di SDK v3 blok catch di bawah inilah permukaan API yang sesungguhnya, dan ada gunanya tahu persis apa yang mendarat di sana. (Untuk menentukan kapan transaksi memang panggilan yang tepat, lihat transaksi DynamoDB.)
Kode
import {DynamoDBClient, TransactWriteItemsCommand} from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({region: 'us-east-1'});
// Move one award between two songs — atomically. If the first song has no
// award to give, NEITHER update happens.
const command = new TransactWriteItemsCommand({
TransactItems: [
{
Update: {
TableName: 'Music',
Key: {Artist: {S: 'Arturo Sandoval'}, SongTitle: {S: 'Cubano Chant'}},
UpdateExpression: 'SET #upd0 = #upd0 - :one',
ConditionExpression: '#upd0 >= :one',
ExpressionAttributeNames: {'#upd0': 'Awards'},
ExpressionAttributeValues: {':one': {N: '1'}}
}
},
{
Update: {
TableName: 'Music',
Key: {Artist: {S: 'Arturo Sandoval'}, SongTitle: {S: 'A Mis Abuelos'}},
UpdateExpression: 'SET #upd0 = if_not_exists(#upd0, :zero) + :one',
ExpressionAttributeNames: {'#upd0': 'Awards'},
ExpressionAttributeValues: {':one': {N: '1'}, ':zero': {N: '0'}}
}
}
]
});
try {
await client.send(command);
console.log('Transaction committed');
} catch (err) {
if (err.name === 'TransactionCanceledException') {
// One reason per action, in TransactItems order. 'None' means that action
// was fine — some OTHER action sank the transaction.
const codes = (err.CancellationReasons ?? []).map((r) => r.Code);
console.log('Transaction canceled:', codes); // e.g. ['ConditionalCheckFailed', 'None']
} else {
throw err;
}
}Penjelasan
TransactItems— array terurut berisi aksiPut,Update,Delete, danConditionCheck. Urutannya bukan urutan eksekusi (transaksinya atomik), tetapi ia adalah urutan kembalinya alasan kegagalan, dan hanya itulah alasan untuk memedulikannya. Batasnya dibahas di bawah.- Apa yang sebenarnya dilempar v3. Properti milik objek yang tertangkap adalah
$fault,$retryable,$metadata,name,CancellationReasons,message, dan__type. Tidak adaerr.code;err.nameadalah string yang harus Anda pakai untuk switch, danerr.$metadatamembawahttpStatusCode: 400plusattempts: 1, yang memberi tahu Anda bahwa SDK tidak diam-diam mencoba ulang pembatalan itu untuk Anda. CancellationReasonsbersifat posisional dan jarang terisi penuh. Untuk transaksi di atas ia datang sebagai[{"Code":"ConditionalCheckFailed","Message":"The conditional request failed"},{"Code":"None"}]. EntriNonesama sekali tidak punya propertiMessage, jadierr.CancellationReasons.map((r) => r.Message.trim())melempar error di dalam error handler Anda justru pada aksi-aksi yang berhasil.ReturnValuesOnConditionCheckFailure: 'ALL_OLD'menambahkan sebuahItemke alasan aksi tersebut, di depanCodedanMessage, dalam DynamoDB JSON mentah. Atribut item yang kalah kembali secara cuma-cuma; alternatifnya adalahGetItemsusulan setelah Anda telanjur kalah balapan.- Pemeriksaan
err.namepunya satu lubang, dan ada gunanya tahu yang mana. Arahkan dua aksi ke item yang sama dan DynamoDB menjawabValidationExceptiondengan pesanTransaction request cannot include multiple operations on one item, dan tanpaCancellationReasonssama sekali, karena tidak ada yang dicoba. Cabangelse { throw err }di atas melempar ulang error itu. Itu perilaku yang benar, bukan bug, tetapi artinya kesalahan struktural tidak pernah sampai ke logging pembatalan Anda. - v3 sudah mengirim
ClientRequestToken, bahkan ketika Anda menghilangkannya. Menangkap body terserialisasi memperlihatkan UUID baru di jalur transport, dan dua panggilansend()atas objek command yang sama berangkat dengan dua token berbeda. Jadi token itu melindungi satu panggilan yang sedang berjalan, bukan loop retry Anda sendiri: catch, kirim ulang, dan Anda punya token baru tanpa idempotensi. Sediakan token Anda sendiri kalau percobaan ulangnya bisa melintasi batas proses. Pakai ulang token itu dengan satu parameter yang diubah dan Anda mendapatIdempotentParameterMismatchalih-alih penerapan ganda yang senyap. - Hanya satu kode lain yang butuh jalur kode tersendiri.
TransactionConflictberarti transaksi lain sedang memegang salah satu item Anda, jadi percobaan ulang dengan backoff adalah respons yang tepat — sesuatu yang tidak pernah tepat untukConditionalCheckFailed. Sisanya diuraikan di halaman TransactionCanceledException. - Biaya — setiap item dalam sebuah transaksi ditulis dua kali di baliknya (prepare, lalu commit), jadi anggarkan kira-kira 2× write capacity dari penulisan biasa. Sebuah penulisan bersyarat satu item memberi Anda atomisitas pada satu item dengan separuh biaya itu.
Batas mana yang Anda tabrak lebih dulu
Batas 100 aksi dan batas 4 MB saling bebas, dan yang berbasis byte itulah yang mengejutkan orang: seratus penambahan counter bukan apa-apa, sementara selusin item gemuk bisa menghabiskan agregatnya sendirian. Ukur satu item representatif dengan kalkulator ukuran item DynamoDB sebelum Anda memutuskan berapa banyak aksi yang di-batch. Untuk membaca item yang akan disentuh sebuah aksi sementara Anda masih menulis kondisinya, unduh DynoTable.
Contoh terkait
- DynamoDB TransactWriteItems di Python — transaksi yang sama dengan boto3.
- DynamoDB TransactWriteItems dengan AWS CLI — transaksi yang sama dari shell.
- Penulisan bersyarat DynamoDB di Node.js — atomisitas satu item tanpa biaya 2×.
- Transaksi DynamoDB — isolasi, idempotensi, dan kapan transaksi sepadan.
- DynamoDB TransactionCanceledException — setiap kode alasan pembatalan, diuraikan.
- "Too many actions in a TransactWriteItems call" — batas 100 aksi dan 4 MB per transaksi.
- "Transaction request cannot include multiple operations on one item" — satu aksi per item, per transaksi.
Referensi
- TransactWriteItems — Amazon DynamoDB API Reference
- Amazon DynamoDB transactions: how it works — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
Terakhir diverifikasi 2026-07-28 terhadap dokumentasi resmi AWS yang ditautkan di atas.