Node.js'te DynamoDB Koşullu Yazma (AWS SDK v3)
AWS SDK v3'te koşullu bir yazmanın ilginç kısmı, her yerde aynı çalışan ve DynamoDB koşul ifadeleri sayfasında ele alınan ConditionExpression değildir. İlginç olan başarısızlık yoludur: v3, istediyseniz kaybeden öğeyi fırlatılan hatanın üzerinde size verir, istemediyseniz hiçbir şey vermez.
Kod
import {DynamoDBClient, UpdateItemCommand} from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({region: 'us-east-1'});
// Update the item only if nobody changed it since we read version 7.
const command = new UpdateItemCommand({
TableName: 'Music',
Key: {
Artist: {S: 'Arturo Sandoval'},
SongTitle: {S: 'Cubano Chant'}
},
UpdateExpression: 'SET #upd0 = :updValue0, #version = :newVersion',
ConditionExpression: 'attribute_exists(#cond0) AND #version = :expectedVersion',
ExpressionAttributeNames: {
'#upd0': 'Genre',
'#version': 'Version',
'#cond0': 'Artist'
},
ExpressionAttributeValues: {
':updValue0': {S: 'Latin Jazz'},
':expectedVersion': {N: '7'},
':newVersion': {N: '8'}
},
ReturnValuesOnConditionCheckFailure: 'ALL_OLD'
});
try {
await client.send(command);
console.log('Updated to version 8');
} catch (err) {
if (err.name === 'ConditionalCheckFailedException') {
// With ReturnValuesOnConditionCheckFailure: 'ALL_OLD', the current item
// rides back on the exception — no extra read to see what beat you.
console.log('Lost the race — item is now:', err.Item);
} else {
throw err;
}
}Açıklama
- Başarısız denetim, bir durum alanı değil, fırlatılan bir hatadır. v3 promise'i reddeder; dolayısıyla yazma yolu ile yarışı kaybetme yolu farklı dallardır.
err.name === 'ConditionalCheckFailedException'ayırt edicidir; başka her şey yeniden fırlatılmalıdır — bloktakielsebunun içindir. Tümcatch'i yutarsanız bir kısıtlamayı sessizce işlemsiz bir çağrıya dönüştürmüş olursunuz. - Sizi kimin geçtiğini görmenin tek yolu
ReturnValuesOnConditionCheckFailure'dır. O olmadan hata yalnızca mesajı taşır, başka bir şey taşımaz ve ihtiyacınız olmayan birGetItem'a geri dönmüş olursunuz. API başvurusu geçerli değerleriniALL_OLD | NONEolarak belirler ve hiç okuma kapasitesi tüketmediğini doğrular. err.Itemham birAttributeValueeşlemesidir, gönderdiğinizKeyile aynı biçimdedir, düz JavaScript değil.Version'ı bir sayıyla karşılaştırmadan önce onu@aws-sdk/util-dynamodb'dekiunmarshall'dan geçirin, yoksa{N: '9'}ile karşılaştırıyor olursunuz.- Başarısız yazma yine de faturalandırılır. Developer Guide, yanlış değerlendirilen bir koşulun yine de yazma kapasitesi tükettiğini ve bunun eski ile yeni öğeden büyüğüne göre boyutlandığını açıkça söyler. Sıcak bir anahtar üzerindeki bir yeniden deneme döngüsü faturada gerçek bir kalemdir; bu yüzden deneme sayısını sınırlayın.
- Bloktaki her ad takma adlıdır (
#version→Version,#cond0→Artist), çünkü onu üreten Expression Builder koşulsuz olarak takma ad verir. Bu burada gerekenden ağırdır ve asla yanlış değildir — yaptığı takas budur.
Kaybedenin kopyasını istisnadan okumak
Saklanan Version'ı 9 yapın ve 7 bekleyen bloğu çalıştırın. DynamoDB Local 3.3.0 hata fırlatır ve yakalanan hata şunları taşır:
err.name ConditionalCheckFailedException
err.message The conditional request failed
err.$metadata.httpStatusCode 400
err.Item {
Artist: { S: 'Arturo Sandoval' },
Year: { N: '1994' },
Version: { N: '9' },
SongTitle: { S: 'Cubano Chant' },
AlbumTitle: { S: 'Danzon' }
}O Version: 9 işin bütün özüdür. Yeniden deneme, :expectedVersion 9 yapılarak doğrudan güncellemeye geri dönebilir — fazladan okuma olmadan ve GetItem'ınız ile yeniden denemeniz arasına üçüncü bir yazarın sızabileceği bir pencere olmadan.
Aynı komuttan ReturnValuesOnConditionCheckFailure'ı silin ve yeniden çalıştırın. Aynı name, aynı message, aynı 400 ve err.Item undefined. Hiçbir şey sizi uyarmaz: parametre isteğe bağlıdır, yokluğu bir hata değildir ve err.Item'ı okuyan kod üretimde undefined günlüklemeye başlar.
Ayrıca buradaki bir 400'ün hatalı biçimlendirilmiş bir istek anlamına gelmediğini de not edin. ValidationException ve ConditionalCheckFailedException aynı durum kodunu paylaşır ve yalnızca biri bir hatadır; dallanmanın durum koduna değil, err.name'e göre olmasının nedeni budur.
Bir koşulun kendi verinize karşı başarılı ve başarısız olmasını, ifadeyi elle yazmak yerine sizin için yazdırarak izlemek için DynoTable'ı indirin.
İlgili örnekler
- Python'da DynamoDB koşullu yazma — boto3 ile aynı iyimser kilit.
- AWS CLI ile DynamoDB koşullu yazma — kabuktan aynı iyimser kilit.
- Node.js'te DynamoDB PutItem — yalnızca-oluştur
attribute_not_existsput'u. - DynamoDB koşul ifadeleri — desenleriyle birlikte her işlev.
- Birden çok öznitelikte benzersizliği zorlama — koşullar + işlemler bir arada.
- DynamoDB ConditionalCheckFailedException — başarısız denetim beklendiğinde ve onu ucuza nasıl ele alacağınız.
Kaynaklar
- UpdateItem — Amazon DynamoDB API Reference
- Condition expressions — 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ı.