DynamoDB TransactWriteItems di Python (boto3)
Transaksi adalah salah satu tempat di mana dua API boto3 paling berjauhan: transact_write_items hanya ada pada client tingkat rendah, jadi kenyamanan tipe-Python-native yang Anda dapat dari Table tidak tersedia di sini. Dan ketika transaksinya gagal, yang Anda butuhkan berada di sudut exception yang jarang dilihat kode boto3 mana pun. (Apa yang Anda dapat dari sebuah transaksi sama di setiap SDK.)
Kode
import boto3
client = boto3.client("dynamodb")
# Move one award between two songs — atomically. If the first song has no
# award to give, NEITHER update happens.
try:
client.transact_write_items(
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"}},
}
},
]
)
print("Transaction committed")
except client.exceptions.TransactionCanceledException as e:
# One reason per action, in TransactItems order. Code "None" means that
# action was fine — some OTHER action sank the transaction.
codes = [reason["Code"] for reason in e.response["CancellationReasons"]]
print(f"Transaction canceled: {codes}") # e.g. ['ConditionalCheckFailed', 'None']Penjelasan
TransactItems— sebuah list berisi dictPut,Update,DeletedanConditionCheck, setiap nilainya dalam DynamoDB JSON, tanpa pengecualian. Ini satu-satunya panggilan boto3 di mana bentuk bertipe itu bukan pilihan, dan itulah alasan bagian di akhir halaman ini ada. Batasannya ada di halaman CLI.CancellationReasonstidak berada di dalamError. botocore mengangkat field error yang dimodelkan ke tingkat teratas dict respons, jadi exception yang tertangkap membawae.responsedengan keyCancellationReasons,Error,MessagedanResponseMetadataberdampingan. Mencarinya di bawahe.response["Error"]tidak menemukan apa pun, dane.response["Error"]hanya berisi kode dan pesan ringkasnya.- Tidak ada
"Message"pada entriNone— alasan untuk aksi yang berhasil adalah dict berkunci tunggal{"Code": "None"}, jadi[r["Message"] for r in reasons]yang tampak alami itu melemparKeyError: 'Message'tepat pada aksi-aksi yang berhasil. Pakair.get("Message"). - Kelas exception yang dibangkitkan — botocore membangun
client.exceptions.TransactionCanceledExceptiondari model layanan saat runtime, itulah sebabnya ia menempel pada instance client dan sebabnya Anda tidak bisafrom botocore.exceptions import ...untuknya. Di dalam helper yang tidak punya client dalam scope, tangkapbotocore.exceptions.ClientErrordan bercabanglah padae.response["Error"]["Code"]; kelas yang dibangkitkan itu subclass-nya. - Kesalahan struktural tidak datang sebagai pembatalan, jadi klausa
exceptdalam cuplikan itu tak pernah melihatnya. Dua aksi yang menyasar item yang sama melemparClientErrorpolos dengan kodeValidationExceptiondane.response-nya tidak punya keyCancellationReasons, karena transaksinya ditolak sebelum aksi mana pun berjalan. TangkapClientErrordi lapisan terluar kalau Anda ingin itu tercatat dengan konteks yang sama. ReturnValuesOnConditionCheckFailure: "ALL_OLD"pada sebuah aksi menaruh item yang kalah di bawah keyItemdalam alasan aksi tersebut, dalam DynamoDB JSON, sehingga Anda tak perluget_itemsusulan setelah kalah balapan.- boto3 mengisi
ClientRequestTokenuntuk Anda. Ditangkap di wire, dua panggilantransact_write_itemsyang identik berangkat dengan dua UUID berbeda, jadi token itu mencakup satu panggilan saja dan bukan loop catch-and-retry Anda sendiri. Berikan token yang stabil sendiri kalau percobaan ulangnya bisa hidup lebih lama dari proses Anda. - Coba ulang pada
TransactionConflict, jangan pernah padaConditionalCheckFailed— yang pertama berarti orang lain memegang item itu sesaat; yang kedua berarti prasyarat Anda salah dan akan tetap salah lain kali. Hanya dua kode itu yang perlu dipisahkan sebagian besar handler, dan set lengkapnya diuraikan di halaman TransactionCanceledException. - Biaya — penulisan transaksional menagih kira-kira dua kali lipat penulisan yang sama di luar transaksi, diukur di halaman CLI. Kalau Anda hanya butuh atomisitas pada satu item, penulisan bersyarat memberikannya dengan setengah harga.
Tidak ada versi API resource untuk yang satu ini
boto3.resource("dynamodb").Table(...) tidak punya atribut transact_write_items; hanya resource.meta.client yang punya. Jadi codebase yang sudah mapan dengan Table dan tipe Python native harus mundur ke DynamoDB JSON bertipe untuk transaksinya, atau melakukan serialisasi manual dengan boto3.dynamodb.types.TypeSerializer:
from boto3.dynamodb.types import TypeSerializer
serialize = TypeSerializer().serialize
values = {k: serialize(v) for k, v in {":one": 1, ":zero": 0}.items()}TypeSerializer menerapkan aturan yang sama dengan API resource, artinya ia menolak float dan mengharapkan decimal.Decimal untuk apa pun yang pecahan. Konverter DynamoDB JSON melakukan konversi yang sama di browser ketika Anda cuma perlu menempelkan sebuah literal ke dalam skrip. Untuk menyunting item yang disentuh sebuah transaksi tanpa menulis kedua bentuk itu secara manual, unduh DynoTable.
Contoh terkait
- DynamoDB TransactWriteItems di Node.js — transaksi yang sama dengan AWS SDK v3.
- DynamoDB TransactWriteItems dengan AWS CLI — transaksi yang sama dari shell.
- Penulisan bersyarat DynamoDB di Python — atomisitas satu item tanpa biaya 2×.
- Transaksi DynamoDB — isolasi, idempotensi, dan kapan transaksi sepadan.
- DynamoDB TransactionCanceledException — setiap kode cancellation reason, 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
- DynamoDB.Client.transact_write_items — Boto3 documentation
- 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.