DynamoDB ReturnValues: das alte oder neue Item bekommen
Standardmäßig gibt ein DynamoDB-Schreibvorgang nichts außer Erfolg zurück. Oft brauchst du aber die Daten
rund um den Schreibvorgang — den Wert vor deiner Änderung oder den frischen Wert danach. Die
naive Lösung ist ein zweites GetItem, und das ist ein zusätzlicher Round Trip und ein Race: Jemand
anderes kann dazwischen schreiben. DynamoDB vermeidet beides mit dem Parameter ReturnValues,
der dir das alte oder neue Item atomar als Teil des Schreibvorgangs selbst zurückgibt.
Was macht ReturnValues in DynamoDB?
ReturnValues weist einen DynamoDB-Schreibvorgang an, das Item als Teil desselben Aufrufs zurückzugeben, sodass du ein zweites GetItem und das dadurch entstehende Race sparst. PutItem und DeleteItem akzeptieren NONE oder ALL_OLD; UpdateItem akzeptiert alle fünf (NONE, ALL_OLD, UPDATED_OLD, ALL_NEW, UPDATED_NEW) und gibt alte oder neue Werte atomar zurück.
ReturnValuesgibt das Item als Teil des Schreibvorgangs zurück — kein zweiter Lesevorgang, kein Race.NONE(Standard) — gibt nichts zurück.ALL_OLD— das gesamte Item, so wie es vor dem Schreibvorgang war.UPDATED_OLD— nur die vom Update geänderten Attribute, mit den Werten davor.ALL_NEW— das gesamte Item nach dem Schreibvorgang.UPDATED_NEW— nur die geänderten Attribute, mit den Werten danach.PutItem/DeleteItemakzeptieren nurNONEoderALL_OLD;UpdateItemakzeptiert alle fünf.
Das Problem: du brauchst den Wert, den du gerade überschrieben hast
Angenommen, du betreibst einen Support-Desk und eine Agentin ändert den Status eines Tickets von open auf
pending. Dein Audit-Log muss festhalten, welchen Status es vorher hatte.
Ohne ReturnValues würdest du:
GetItem, um den aktuellen Status zu lesen,UpdateItem, um den neuen zu setzen.
Zwischen Schritt 1 und 2 könnte ein anderer Agent den Status ändern — jetzt hält dein Audit-Log einen
veralteten „Vorher“-Wert fest. Schlimmer noch: Es sind zwei Aufrufe für eine logische Operation. ReturnValues
faltet das in ein einziges atomares UpdateItem, das den alten Status so zurückgibt, wie er
zum Zeitpunkt des Schreibens tatsächlich war.
Die fünf Optionen und wann du welche nimmst
UpdateItem unterstützt den vollen Satz; die Wahl hängt davon ab, welchen Ausschnitt des Items und welche
Seite des Schreibvorgangs du brauchst:
ReturnValues | Gibt zurück | Nimm es, wenn |
|---|---|---|
NONE | nichts | du das Item nicht zurückbrauchst (Standard) |
ALL_OLD | ganzes Item, vor dem Schreiben | Auditing / „was habe ich gerade ersetzt?“ |
UPDATED_OLD | geänderte Attribute, vor dem Schreiben | dich nur die Felder interessieren, die du angefasst hast |
ALL_NEW | ganzes Item, nach dem Schreiben | du das frische vollständige Item an einen Aufrufer zurückgeben musst |
UPDATED_NEW | geänderte Attribute, nach dem Schreiben | du einen gerade erhöhten Zähler/Wert zurücklesen willst |
UPDATED_NEW ist der Alltagsheld: Erhöhe einen Zähler mit einer
Update Expression und lies die neue Summe im selben Aufruf
zurück, ohne Race. Für das Support-Ticket-Audit hält ALL_OLD (oder UPDATED_OLD, wenn
du nur das Statusfeld loggst) den Zustand vor der Änderung atomar fest.
Beachte die Asymmetrie: PutItem und DeleteItem unterstützen nur NONE und ALL_OLD —
bei einem Delete gibt es keinen „neuen“ Wert zurückzugeben, und der neue Wert eines Put ist genau das, was du
geschickt hast. Nur UpdateItem, das in-place verändert, bietet alle fünf.
AWS dokumentiert
die exakte Matrix.
Das Update in DynoTable schreiben
Setze das UpdateItem und seine Update Expression visuell mit dem
DynamoDB Expression Builder zusammen — er gibt die
SET/ADD-Klausel plus die Attributnamen- und Wert-Maps aus. In der App zeigt DynoTable
das resultierende Item, nachdem ein gestagter Schreibvorgang committet wurde, sodass du den neuen Zustand
direkt siehst.

Fallstricke + nächste Schritte
- Kein
GetItem-dann-Schreiben, um rund um eine Änderung zu lesen — das ist ein Round Trip und ein Race; nimmReturnValues. UPDATED_*gibt nur die angefassten Attribute zurück — brauchst du das ganze Item, nimmALL_*.PutItem/DeleteItemkönnen keine neuen Werte zurückgeben — nurNONE/ALL_OLD.ReturnValuesersetzt keine Bedingung — um einen Schreibvorgang zu schützen, ergänze eine Condition Expression; um seine Wirkung zurückzulesen, nimmReturnValues. Beides lässt sich kombinieren.- Verwandt: Update Expressions, atomare Zähler.
Du willst Änderungen machen und Vorher/Nachher sehen, ohne zwei Aufrufe zu skripten? Lade DynoTable herunter und bearbeite deine Items direkt.
Atomarer Zähler mit UPDATED_NEW
Bestandssysteme erhöhen bei jedem Schreibvorgang ein Feld version oder stock. Das
Muster ist ein UpdateItem mit ADD stock :inc und ReturnValues: UPDATED_NEW:
UpdateItem PK=SKU#8842
UpdateExpression: ADD stock :one
ExpressionAttributeValues: {":one": {"N": "1"}}
ReturnValues: UPDATED_NEW
→ Attributes.stock.N == "41" (was 40)Du erhältst nur die Map der geänderten Attribute, nicht das ganze Item — ideal, wenn das
Item groß ist, der Aufrufer aber nur den neuen Zähler braucht. Für Audit-Trails, die jedes Feld vor
der Änderung festhalten müssen, wechsle auf ALL_OLD.
Der Schreibvorgang wird weiterhin als UpdateItem auf Basis der Item-Größe abgerechnet; ReturnValues erzeugt
keine separate Lesegebühr — DynamoDB hat das Item ohnehin geladen, um das
Update anzuwenden.
Hinweis zur Kapazität
Attribute zurückzugeben verdoppelt die WCU-Kosten des Schreibvorgangs nicht. Du zahlst für den Schreibvorgang gemäß den AWS-Regeln auf Basis der Item-Größe vor und nach dem Update, unabhängig davon, wie viele Attribute in der Response auftauchen.
Wärst du versucht gewesen, erst GetItem und dann UpdateItem aufzurufen, um den alten Wert zu loggen, hättest du
einen Lese- plus einen Schreibvorgang bezahlt. ReturnValues: ALL_OLD am Update entfernt den
Lesevorgang vollständig — bei einem 2-KB-Item und 500 Updates pro Sekunde spart das rund
250 letztendlich konsistente RCU pro Sekunde.
Mit Condition Expressions kombinieren
ReturnValues und
Condition Expressions lassen sich im
selben Aufruf kombinieren. Beispiel: retryCount nur erhöhen, solange er unter einer Obergrenze liegt, und den
neuen Stand zurückgeben:
ConditionExpression: retryCount < :max
UpdateExpression: ADD retryCount :one
ReturnValues: UPDATED_NEWScheitert die Bedingung, gibt DynamoDB eine ConditionalCheckFailedException und
kein Attribut-Payload zurück — zu unterscheiden von einem erfolgreichen Update mit leerem
UPDATED_NEW, wenn sich nichts geändert hat.
Nutze den Expression Builder, um die
UpdateExpression, die Bedingung und die gemarshallten Wert-Maps gemeinsam zu erzeugen.
Entscheidungshilfe
| Du brauchst … | Einstellung | Funktioniert bei |
|---|---|---|
| Nichts zurück | NONE | Put, Update, Delete |
| Ganzes Item vor Überschreiben/Löschen | ALL_OLD | Put, Update, Delete |
| Nur geänderte Felder, davor | UPDATED_OLD | Update |
| Ganzes Item nach dem Patch | ALL_NEW | Update |
| Nur geänderte Felder, danach | UPDATED_NEW | Update |
Deletes und Puts
DeleteItem mit ReturnValues: ALL_OLD ist der Weg, „Pop and Return“-Semantik
auf einem Queue-Item umzusetzen — die gelöschte Zeile kommt in Attributes zurück. Es gibt
kein ALL_NEW beim Delete, weil das Item danach nicht mehr existiert.
PutItem mit ALL_OLD gibt das vorherige Item zurück, wenn du einen bestehenden
Key überschreibst — nützlich für Swap-Abläufe. Existierte der Key nicht, lässt die Response
Attributes weg.
In DynoTable nachprüfen
Stage eine Attributänderung im Item-Editor: Der Review-Bereich zeigt alte und neue
Werte vor dem Commit nebeneinander — dieselbe Information, die UPDATED_OLD und
UPDATED_NEW zurückgeben würden, ganz ohne Skript. Nach dem Commit kopierst du die Zeile über
die Export-Aktionen des Grids als JSON für Testfixtures.


