Lanjutan6 menit baca

Transaksi DynamoDB

Sebuah transaksi DynamoDB mengelompokkan beberapa penulisan ke dalam satu operasi all-or-nothing: entah setiap aksi ter-commit, atau tidak ada yang ter-commit. Inilah cara Anda menjaga dua Item yang berhubungan agar tidak menyimpang ketika sebuah penulisan setengah-gagal.

Dalam skenario audit-log, setiap event yang Anda tambahkan juga harus menaikkan eventCount per tenant. Jika event mendarat tetapi counter tidak — atau sebaliknya — log dan hitungan akan selamanya berbeda. Sebuah transaksi membuat itu mustahil.

Apakah DynamoDB mendukung transaksi?

Ya. DynamoDB mendukung transaksi ACID melalui TransactWriteItems dan TransactGetItems, yang mengelompokkan hingga 100 aksi ke dalam satu operasi all-or-nothing lintas satu atau lebih tabel. Setiap penulisan ter-commit atau tidak ada yang ter-commit, sehingga Item yang berhubungan tidak dapat menyimpang. Penulisan transaksional mengonsumsi dua kali kapasitas penulisan normal, dan condition yang gagal atau konflik membatalkan seluruh request.

  • TransactWriteItems mengelompokkan hingga 100 aksi penulisan lintas satu atau lebih tabel, all-or-nothing. Ukuran Item agregat tidak boleh melebihi 4 MB.
  • Aksinya adalah Put, Update, Delete, dan ConditionCheck. Sebuah ConditionCheck menegaskan sesuatu tentang sebuah Item yang tidak Anda tulis.
  • Biayanya dua kali lipat. Sebuah penulisan transaksional mengonsumsi dua kali kapasitas penulisan normal — DynamoDB menyiapkan lalu meng-commit.
  • Konflik dan condition yang gagal membatalkan keseluruhannya dengan TransactionCanceledException; tidak ada yang parsial tertinggal.

Masalahnya: dua penulisan yang harus sepakat

Anda ingin setiap event audit baru juga menaikkan hitungan berjalan tenant. Dilakukan sebagai dua panggilan terpisah, kegagalan apa pun di antaranya merusak data Anda:

  1. PutItem Item EVENT#… baru — berhasil.
  2. UpdateItem ke ADD eventCount 1 — timeout.

Sekarang log punya satu baris lebih banyak daripada yang diklaim counter. Mencoba ulang langkah 2 secara membuta berisiko menghitung ganda; tidak mencoba ulang membuatnya tidak konsisten. Tidak ada pemulihan yang aman karena dua penulisan itu tidak pernah ditautkan.

Datang dari SQL, Anda akan membungkus keduanya dalam BEGIN … COMMIT. Jawaban DynamoDB adalah sebuah request transaksional tunggal yang membawa kedua penulisan bersama-sama.

Cara kerja TransactWriteItems

Menurut AWS Developer Guide, TransactWriteItems "mengelompokkan hingga 100 aksi penulisan dalam satu operasi all-or-nothing" menargetkan hingga 100 Item berbeda, dan "ukuran agregat dari Item dalam transaksi tidak boleh melebihi 4 MB." Aksi-aksinya selesai secara atomik — semua berhasil atau tidak ada.

Anda dapat mencampur empat tipe aksi dalam satu transaksi:

  • Put — membuat atau mengganti sebuah Item.
  • Update — mengedit atribut (termasuk ADD untuk counter kita).
  • Delete — menghapus sebuah Item berdasarkan key.
  • ConditionCheck — menegaskan sebuah condition pada Item yang tidak Anda tulis (mis. "tenant ini masih aktif").

Dua aturan lagi menggigit dalam praktik. Pertama, transaksi mengonsumsi dua kali kapasitas dari penulisan non-transaksional yang setara — DynamoDB melakukan fase prepare dan fase commit. Kedua, Anda tidak dapat menargetkan Item yang sama dua kali dalam satu transaksi, dan transaksi tidak dapat dilakukan terhadap index.

"DynamoDB"App"DynamoDB"Appprepare both, checkconditions"TransactWriteItems [Put EVENT,Update counter]""both commit, orTransactionCanceledException"

Contoh terkerjakan: append + hitung, secara atomik

Kembali ke audit log. Menambahkan sebuah event untuk tenant acme dan menaikkan counter-nya adalah satu transaksi dengan dua aksi:

actionitemeffect
PutTENANT#acmeEVENT#2026-06-24T09:14Z#a1write the new audit row
UpdateTENANT#acmeCOUNTERADD eventCount 1

Jika condition aksi mana pun gagal — katakanlah sebuah ConditionCheck bahwa tenant tidak ditangguhkan — seluruh request dibatalkan dengan TransactionCanceledException dan tidak satu pun penulisan terjadi. Log dan counter tidak pernah bisa berbeda.

ConditionExpression pada setiap aksi adalah tuasnya. Untuk menegaskan baris event belum ada (sehingga sebuah retry tidak bisa menduplikasinya) dan tenant aktif, Anda menyusun condition seperti attribute_not_exists(SK) pada Put dan status = :active sebagai sebuah ConditionCheck.

Bangun dan salin condition expression bertipe itu di DynamoDB Expression Builder alih-alih merakit ExpressionAttributeNames dan placeholder :val dengan tangan — mode conditional-write mengeluarkan persis bentuk yang diinginkan TransactWriteItems.

Untuk retry yang aman pada koneksi yang labil, lampirkan sebuah client token: sebuah TransactWriteItems yang diulang dengan token yang sama dalam 10 menit mengembalikan sukses tanpa menerapkan ulang penulisannya (idempotency).

Lakukan di DynoTable

DynoTable menggunakan transaksi di balik layar untuk penulisannya sendiri: saat Anda men-stage beberapa edit Item dan meng-commit-nya, ia mengirimkannya sebagai TransactWriteItems dengan condition expression optimistic-locking, sehingga batch edit Anda bersifat all-or-nothing — Anda tidak pernah setengah-menerapkan perubahan multi-Item.

Itu berarti Anda dapat mengedit baris event dan counter dalam batch yang sama yang di-stage, meninjau diff-nya, dan meng-commit keduanya secara atomik tanpa menulis kode SDK apa pun.

Men-stage event audit baru dan edit counter tenant di DynoTable, lalu meng-commit keduanya sebagai satu transaksi all-or-nothing.
Men-stage event audit baru dan edit counter tenant di DynoTable, lalu meng-commit keduanya sebagai satu transaksi all-or-nothing.

Jebakan dan langkah berikutnya

  • Anggarkan untuk kapasitas ganda. Sebuah penulisan transaksional menagih dua kali WCU dari penulisan biasa — baik-baik saja untuk pasangan kritis-konsistensi sesekali, mahal jika Anda membungkus setiap penulisan tunggal dalam transaksi. Gunakan di mana atomisitas benar-benar penting.
  • Tangani TransactionCanceledException secara eksplisit. Ia dikembalikan untuk condition yang gagal atau konflik dengan transaksi lain yang sedang berjalan pada Item yang sama. Alasan pembatalan memberi tahu Anda aksi mana yang gagal — periksa, jangan retry membuta.
  • Record stream tidak sadar transaksi. Perubahan dari satu transaksi menyebar ke Streams secara bertahap dan dapat berselang-seling dengan yang lain; consumer tidak dapat mengasumsikan atomisitas atau pengurutan — lihat DynamoDB Streams.
  • Bukan untuk counter throughput-tinggi. Sebuah hot counter tunggal di bawah beban transaksional konkuren yang berat akan men-throttle; untuk itu, lihat atomic counter atau sharding counter-nya.

Transaksi adalah alat untuk "penulisan ini harus sepakat." Begitu event mendarat secara konsisten, perhatian berikutnya adalah bereaksi terhadapnya — itulah DynamoDB Streams.

Unduh DynoTable untuk men-stage edit multi-Item dan meng-commit-nya sebagai satu transaksi terhadap tabel Anda sendiri.

Diperbarui