Fortgeschritten3 Min. Lesezeit

DynamoDB ReturnValues: Das alte oder neue Item aus einem Write holen

Standardmäßig gibt ein DynamoDB-Write nichts außer Erfolg zurück. Aber oft brauchst du die Daten rund um den Write — den Wert, bevor du ihn geändert hast, oder den frischen Wert danach. Der naive Fix ist ein zweites GetItem, was ein zusätzlicher Round-Trip und ein Race ist: jemand anderes kann dazwischen schreiben. DynamoDB umgeht beides mit dem Parameter ReturnValues, der das alte oder neue Item atomar als Teil des Writes selbst zurückreicht.

Was macht ReturnValues in DynamoDB?

ReturnValues weist einen DynamoDB-Write an, das Item als Teil desselben Aufrufs zurückzugeben, sodass du ein zweites GetItem und den damit verbundenen Race vermeidest. 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.

  • ReturnValues gibt das Item als Teil des Writes zurück — kein zweiter Read, kein Race.
  • NONE (Standard) — nichts zurückgeben.
  • ALL_OLD — das gesamte Item so, wie es vor dem Write war.
  • UPDATED_OLD — nur die Attribute, die das Update geändert hat, vorher-Werte.
  • ALL_NEW — das gesamte Item nach dem Write.
  • UPDATED_NEW — nur die geänderten Attribute, nachher-Werte.
  • PutItem/DeleteItem akzeptieren nur NONE oder ALL_OLD; UpdateItem akzeptiert alle fünf.

Das Problem: du brauchst den Wert, den du gerade überschrieben hast

Nimm an, du betreibst einen Support-Desk und ein Agent ändert den Status eines Tickets von open auf pending. Dein Audit-Log muss aufzeichnen, was der Status vor der Änderung war. Ohne ReturnValues würdest du:

  1. GetItem, um den aktuellen Status zu lesen,
  2. UpdateItem, um den neuen zu setzen.

Zwischen Schritt 1 und 2 könnte ein anderer Agent den Status ändern — jetzt zeichnet dein Audit-Log einen veralteten „vorher"-Wert auf. Schlimmer noch, es sind zwei Aufrufe für eine logische Operation. ReturnValues kollabiert es in ein einziges atomares UpdateItem, das den alten Status so zurückgibt, wie er zum Write-Zeitpunkt tatsächlich war.

Die fünf Optionen und wann du welche nutzt

UpdateItem unterstützt das volle Set; die Wahl ist welcher Ausschnitt des Items und welche Seite des Writes du brauchst:

ReturnValuesGibt zurückNutze, wenn
NONEnichtsdu das Item nicht zurückbrauchst (Standard)
ALL_OLDganzes Item, pre-WriteAuditing / „was habe ich gerade ersetzt?"
UPDATED_OLDgeänderte Attrs, pre-Writedich nur die angefassten Felder interessieren
ALL_NEWganzes Item, post-Writedu das frische volle Item an einen Aufrufer zurückgeben musst
UPDATED_NEWgeänderte Attrs, post-Writedu einen Zähler/Wert zurückliest, den du gerade erhöht hast

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 erfasst ALL_OLD (oder UPDATED_OLD, wenn du nur das Status-Feld loggst) den Zustand vor der Änderung atomar.

Beachte die Asymmetrie: PutItem und DeleteItem unterstützen nur NONE und ALL_OLD — es gibt keinen „neuen" Wert für einen Delete zurückzugeben, und der neue Wert eines Puts ist einfach das, was du gesendet hast. Nur UpdateItem, das an Ort und Stelle mutiert, bietet alle fünf. AWS dokumentiert die exakte Matrix.

Das Update in DynoTable schreiben

Stelle das UpdateItem und seine Update Expression visuell mit dem DynamoDB Expression Builder zusammen — er emittiert die SET/ADD-Klausel plus die Attribute-Name- und Value-Maps. In der App zeigt DynoTable das resultierende Item, nachdem ein gestageter Write committet wurde, sodass du den neuen Zustand direkt siehst.

Die vorbereitete Änderung eines Items in DynoTable prüfen — die alten und neuen Werte vor dem Committen des Updates.
Die vorbereitete Änderung eines Items in DynoTable prüfen — die alten und neuen Werte vor dem Committen des Updates.

Fallstricke und nächste Schritte

  • Mach kein GetItem-dann-Write, um rund um eine Änderung zu lesen — das ist ein Round-Trip und ein Race; nutze ReturnValues.
  • UPDATED_* gibt nur angefasste Attribute zurück — wenn du das ganze Item brauchst, nutze ALL_*.
  • PutItem/DeleteItem können keine neuen Werte zurückgeben — nur NONE/ALL_OLD.
  • ReturnValues ist kein Ersatz für eine Condition — um einen Write zu schützen, füge eine Condition Expression hinzu; um seinen Effekt zurückzulesen, nutze ReturnValues. Sie ergänzen sich.
  • Verwandt: Update Expressions, atomare Zähler.

Willst du Edits machen und das Vorher/Nachher sehen, ohne zwei Aufrufe zu skripten? Lade DynoTable herunter und bearbeite deine Items direkt.

Aktualisiert