Orta5 dakikalık okuma

DynamoDB ReturnValues: Eski ya da Yeni Öğeyi Alın

DynamoDB'de bir yazma varsayılan olarak başarıdan başka bir şey döndürmez. Ama çoğu zaman yazmanın çevresindeki veriye ihtiyacınız olur — değiştirmeden önceki değere ya da sonraki taze değere. Naif çözüm ikinci bir GetItem'dır; bu hem fazladan bir gidiş-dönüş hem de bir yarış koşuludur: arada başkası yazabilir. DynamoDB ikisini de ReturnValues parametresiyle önler; bu parametre eski ya da yeni öğeyi yazmanın kendisinin parçası olarak atomik biçimde geri verir.

DynamoDB'de ReturnValues ne yapar?

ReturnValues, bir DynamoDB yazmasına öğeyi aynı çağrının parçası olarak geri vermesini söyler; böylece ikinci bir GetItem'ı ve onun yarattığı yarış koşulunu atlarsınız. PutItem ve DeleteItem yalnızca NONE ya da ALL_OLD kabul eder; UpdateItem beşini de kabul eder (NONE, ALL_OLD, UPDATED_OLD, ALL_NEW, UPDATED_NEW) ve eski ya da yeni değerleri atomik olarak döndürür.

  • ReturnValues öğeyi yazmanın parçası olarak döndürür — ikinci okuma yok, yarış koşulu yok.
  • NONE (varsayılan) — hiçbir şey döndürmez.
  • ALL_OLD — öğenin tamamı, yazmadan önceki hâliyle.
  • UPDATED_OLD — yalnızca güncellemenin değiştirdiği attribute'lar, önceki değerleriyle.
  • ALL_NEW — yazmadan sonraki öğenin tamamı.
  • UPDATED_NEW — yalnızca değişen attribute'lar, sonraki değerleriyle.
  • PutItem/DeleteItem yalnızca NONE ya da ALL_OLD kabul eder; UpdateItem beşini de kabul eder.

Sorun: Üzerine yazdığınız değere ihtiyacınız var

Diyelim ki bir destek masası işletiyorsunuz ve bir temsilci bir talebin durumunu open'dan pending'e çeviriyor. Denetim günlüğünüzün, değişiklikten önceki durumun ne olduğunu kaydetmesi gerekiyor. ReturnValues olmadan şunları yapardınız:

  1. Mevcut durumu okumak için GetItem,
  2. Yenisini yazmak için UpdateItem.

Bu iki adım arasında başka bir temsilci durumu değiştirebilir — artık denetim günlüğünüz bayat bir "önce" değeri kaydeder. Dahası, tek bir mantıksal işlem için iki çağrıdır. ReturnValues bunu, eski durumu yazma anındaki gerçek hâliyle döndüren tek ve atomik bir UpdateItem'a indirger.

Beş seçenek ve her birinin ne zaman kullanılacağı

UpdateItem tümünü destekler; seçim, öğenin hangi dilimine ve yazmanın hangi tarafına ihtiyacınız olduğuyla ilgilidir:

ReturnValuesDöndürdüğüKullanım zamanı
NONEhiçbir şeyöğeyi geri almanız gerekmiyorsa (varsayılan)
ALL_OLDtüm öğe, yazmadan öncedenetim / "az önce neyin üzerine yazdım?"
UPDATED_OLDdeğişen attribute'lar, yazmadan önceyalnızca dokunduğunuz alanlar ilginizi çekiyorsa
ALL_NEWtüm öğe, yazmadan sonraçağırana döndürmek için taze ve tam öğe gerekiyorsa
UPDATED_NEWdeğişen attribute'lar, yazmadan sonraaz önce artırdığınız bir sayacı/değeri geri okumak için

UPDATED_NEW gündelik kahramandır: bir update expression ile sayacı artırın ve yeni toplamı aynı çağrıda, yarış koşulu olmadan geri okuyun. Destek talebi denetimi için ALL_OLD (ya da yalnızca durum alanını günlüklüyorsanız UPDATED_OLD) değişiklik öncesi durumu atomik olarak yakalar.

Asimetriye dikkat: PutItem ve DeleteItem yalnızca NONE ve ALL_OLD destekler — bir silme için döndürülecek "yeni" değer yoktur ve bir put'un yeni değeri zaten gönderdiğiniz şeydir. Yerinde değişiklik yapan yalnızca UpdateItem beşini de sunar. Tam matrisi AWS belgeliyor.

Güncellemeyi DynoTable'da yazmak

UpdateItem'ı ve update expression'ını görsel olarak DynamoDB expression builder ile kurun — SET/ADD yan tümcesinin yanı sıra attribute adı ve değer haritalarını da üretir. Uygulamada, staging'e alınmış bir yazma commit edildikten sonra DynoTable ortaya çıkan öğeyi gösterir, böylece yeni durumu doğrudan görürsünüz.

DynoTable'da bir öğenin staging'e alınmış değişikliğini incelemek — güncelleme commit edilmeden önceki eski ve yeni değerler.
DynoTable'da bir öğenin staging'e alınmış değişikliğini incelemek — güncelleme commit edilmeden önceki eski ve yeni değerler.

Tuzaklar ve sonraki adımlar

  • Bir değişikliğin çevresini okumak için GetItem-sonra-yaz yapmayın — bu bir gidiş-dönüş ve bir yarış koşuludur; ReturnValues kullanın.
  • UPDATED_* yalnızca dokunulan attribute'ları döndürür — öğenin tamamı gerekiyorsa ALL_* kullanın.
  • PutItem/DeleteItem yeni değer döndüremez — yalnızca NONE/ALL_OLD.
  • ReturnValues bir koşulun yerini tutmaz — bir yazmayı korumak için bir koşul ifadesi ekleyin; etkisini geri okumak için ReturnValues kullanın. Bunlar birlikte çalışır.
  • İlgili: update expression'lar, atomik sayaçlar.

Düzenleme yapıp öncesini/sonrasını iki çağrı yazmadan görmek ister misiniz? DynoTable'ı indirin ve öğelerinizi doğrudan düzenleyin.

UPDATED_NEW ile atomik sayaç

Envanter sistemleri her yazmada bir version ya da stock alanını artırır. Desen, ADD stock :inc ve ReturnValues: UPDATED_NEW içeren tek bir UpdateItem'dır:

UpdateItem  PK=SKU#8842
  UpdateExpression: ADD stock :one
  ExpressionAttributeValues: {":one": {"N": "1"}}
  ReturnValues: UPDATED_NEW
Attributes.stock.N == "41"   (was 40)

Öğenin tamamını değil, yalnızca değişen attribute haritasını alırsınız — öğe büyükken çağıranın yeni sayaca ihtiyaç duyduğu durumlar için idealdir. Değişiklikten önce her alanı yakalaması gereken denetim izleri için ALL_OLD'a geçin.

Yazma yine öğenin boyutuna göre UpdateItem olarak faturalandırılır; ReturnValues ayrı bir okuma ücreti eklemez — DynamoDB güncellemeyi uygulamak için öğeyi zaten yüklemiştir.

Kapasite notu

Attribute döndürmek yazmanın WCU maliyetini ikiye katlamaz. Yazma için, yanıt yükünde kaç attribute göründüğünden bağımsız olarak, AWS kurallarına göre güncelleme öncesi ve sonrası öğe boyutu üzerinden ödersiniz.

Eski değeri günlüklemek için GetItem sonra UpdateItem yapmaya kalkışsaydınız, bir okuma artı bir yazma ödemiş olurdunuz. Güncellemedeki ReturnValues: ALL_OLD okumayı tamamen ortadan kaldırır — saniyede 500 güncelleme yapılan 2 KB'lık bir öğede bu, saniyede yaklaşık 250 nihai tutarlı RCU tasarruf eder.

Koşul ifadeleriyle birlikte kullanın

ReturnValues ve koşul ifadeleri aynı çağrıda birlikte çalışır. Örnek: retryCount değerini yalnızca bir tavanın altındayken artırın ve yeni sayıyı döndürün:

ConditionExpression: retryCount < :max
UpdateExpression: ADD retryCount :one
ReturnValues: UPDATED_NEW

Koşul başarısız olursa DynamoDB ConditionalCheckFailedException döndürür ve hiç attribute yükü göndermez — bu, hiçbir şey değişmediğinde boş bir UPDATED_NEW ile dönen başarılı bir güncellemeden farklıdır.

UpdateExpression'ı, koşulu ve hazırlanmış değer haritalarını birlikte üretmek için expression builder aracını kullanın.

Karar rehberi

İhtiyacınız…AyarÇalıştığı işlemler
Hiçbir şey dönmesinNONEPut, Update, Delete
Üzerine yazmadan/silmeden önceki tam öğeALL_OLDPut, Update, Delete
Yalnızca değişen alanlar, öncesiUPDATED_OLDUpdate
Yamadan sonraki tam öğeALL_NEWUpdate
Yalnızca değişen alanlar, sonrasıUPDATED_NEWUpdate

Silmeler ve put'lar

ReturnValues: ALL_OLD ile DeleteItem, bir kuyruk öğesinde "çek ve döndür" semantiğini böyle uygularsınız — silinen satır Attributes içinde geri gelir. Silmede ALL_NEW yoktur, çünkü öğe artık mevcut değildir.

ALL_OLD ile PutItem, var olan bir anahtarın üzerine yazdığınızda önceki öğeyi döndürür — takas iş akışları için kullanışlıdır. Anahtar mevcut değilse yanıt Attributes içermez.

DynoTable'da doğrulayın

Öğe düzenleyicisinde bir attribute değişikliğini staging'e alın: inceleme bölmesi, commit'ten önce eski ve yeni değerleri yan yana gösterir — UPDATED_OLD ve UPDATED_NEW değerlerinin döndüreceği bilginin aynısını, üstelik betik yazmadan. Commit'ten sonra ızgaranın dışa aktarım eylemleriyle satırı test verisi olarak JSON biçiminde kopyalayın.

Güncellendi