Python'da (boto3) DynamoDB TransactWriteItems
İşlemler, boto3'ün iki API'sinin en sert ayrıştığı yerlerden biridir: transact_write_items yalnızca düşük düzeyli istemcide bulunur, dolayısıyla Table'dan aldığınız yerel Python türleri rahatlığı burada yoktur. Ve işlem başarısız olduğunda, ihtiyacınız olan şey çoğu boto3 kodunun hiç bakmadığı bir istisna köşesindedir. (Bir işlemin size ne kazandırdığı her SDK'da aynıdır.)
Kod
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']Açıklama
TransactItems—Put,Update,DeleteveConditionChecksözlüklerinden oluşan bir liste; her değer, istisnasız, DynamoDB JSON biçiminde. Tipli biçimin isteğe bağlı olmadığı tek boto3 çağrısı budur ve bu sayfanın sonundaki bölümün var olma nedeni de odur. Üst sınırlar CLI sayfasındadır.CancellationReasons,Error'ın içinde değildir. botocore, modellenmiş hata alanlarını yanıt sözlüğünün en üstüne çıkarır; dolayısıyla yakalanan istisna,CancellationReasons,Error,MessageveResponseMetadataanahtarlarını yan yana taşıyan bire.responsegetirir. Onue.response["Error"]altında aramak hiçbir şey bulmaz vee.response["Error"]yalnızca özet kodu ve mesajı tutar.Nonegirdilerinde"Message"yoktur — başarılı bir eylemin nedeni, tek anahtarlı{"Code": "None"}sözlüğüdür; dolayısıyla doğal görünen[r["Message"] for r in reasons], tam da işe yaramış eylemlerdeKeyError: 'Message'fırlatır.r.get("Message")kullanın.- Üretilmiş bir istisna sınıfı — botocore,
client.exceptions.TransactionCanceledException'ı hizmet modelinden çalışma zamanında kurar; istemci örneğine bağlı olmasının ve onufrom botocore.exceptions import ...diye içe aktaramamanızın nedeni budur. Kapsamında istemci olmayan bir yardımcıdabotocore.exceptions.ClientError'ı yakalayın vee.response["Error"]["Code"]üzerinden dallanın; üretilmiş sınıf onun bir alt sınıfıdır. - Yapısal hatalar iptal olarak gelmez, dolayısıyla parçacıktaki
exceptyan tümcesi onları hiç görmez. Aynı öğeye yönelmiş iki eylem, koduValidationExceptionolan vee.response'undaCancellationReasonsanahtarı bulunmayan çıplak birClientErrorfırlatır, çünkü işlem hiçbir eylem çalışmadan önce reddedilmiştir. Bunların da aynı bağlamla günlüklenmesini istiyorsanız dış kenardaClientErroryakalayın. - Bir eylemdeki
ReturnValuesOnConditionCheckFailure: "ALL_OLD", kaybeden öğeyi o eylemin nedeninde birItemanahtarı altında, DynamoDB JSON biçiminde koyar; böylece yarışı çoktan kaybettikten sonra bir deget_itemyapmanıza gerek kalmaz. ClientRequestToken'ı boto3 sizin için doldurur. Kabloda yakalandığı üzere, birbirinin aynı ikitransact_write_itemsçağrısı iki farklı UUID ile çıktı; yani belirteç tek bir çağrıyı kapsar, kendi yakala-ve-yeniden-dene döngünüzü değil. Yeniden deneme süreçten uzun yaşayabiliyorsa sabit bir tanesini kendiniz geçin.TransactionConflict'te yeniden deneyin,ConditionalCheckFailed'de asla — birincisi öğeyi bir an için başkasının tuttuğunu söyler; ikincisi ön koşulunuzun yanlış olduğunu ve bir dahaki sefere de yanlış olacağını söyler. Çoğu işleyicinin ayırması gereken tek iki kod bunlardır; tam küme TransactionCanceledException sayfasında çözümleniyor.- Maliyet — işlemsel bir yazma, aynı yazmanın işlem dışındaki maliyetinin kabaca iki katını faturalandırır, CLI sayfasında ölçüldüğü gibi. Yalnızca tek bir öğede atomikliğe ihtiyacınız varsa, bir koşullu yazma bunu yarı fiyatına verir.
Bunun kaynak API'si sürümü yoktur
boto3.resource("dynamodb").Table(...)'ın transact_write_items özniteliği yoktur; yalnızca resource.meta.client'ın vardır. Dolayısıyla Table ve yerel Python türlerinde karar kılmış bir kod tabanı, işlemleri için tipli DynamoDB JSON'una geri dönmek ya da boto3.dynamodb.types.TypeSerializer ile elle serileştirmek zorundadır:
from boto3.dynamodb.types import TypeSerializer
serialize = TypeSerializer().serialize
values = {k: serialize(v) for k, v in {":one": 1, ":zero": 0}.items()}TypeSerializer, kaynak API'siyle aynı kuralları uygular; yani float'ı reddeder ve kesirli her şey için decimal.Decimal bekler. DynamoDB JSON dönüştürücüsü, bir betiğe yalnızca bir sabit yapıştırmanız gerektiğinde aynı dönüşümü tarayıcıda yapar. Bir işlemin dokunduğu öğeleri iki biçimden birini elle yazmadan düzenlemek için DynoTable'ı indirin.
İlgili örnekler
- Node.js'te DynamoDB TransactWriteItems — AWS SDK v3 ile aynı işlem.
- AWS CLI ile DynamoDB TransactWriteItems — kabuktan aynı işlem.
- Python'da DynamoDB koşullu yazma — 2× maliyet olmadan tek öğelik atomiklik.
- DynamoDB işlemleri — yalıtım, idempotentlik ve işlemler ne zaman değer.
- DynamoDB TransactionCanceledException — her iptal nedeni kodu, çözümlenmiş hâliyle.
- "Too many actions in a TransactWriteItems call" — 100 eylem ve 4 MB işlem sınırları.
- "Transaction request cannot include multiple operations on one item" — işlem başına, öğe başına bir eylem.
Kaynaklar
- 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
En son 2026-07-28 tarihinde yukarıda bağlantısı verilen resmi AWS belgelerine karşı doğrulandı.