Verwenden Sie Erweiterungen, um DynamoDB Enhanced Client-Operationen anzupassen - AWS SDK for Java 2.x

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Verwenden Sie Erweiterungen, um DynamoDB Enhanced Client-Operationen anzupassen

Die DynamoDB Enhanced Client API unterstützt Plugin-Erweiterungen, die Funktionen bieten, die über Mapping-Operationen hinausgehen. Erweiterungen verwenden zwei Hook-Methoden, um Daten während Lese- und Schreibvorgängen zu ändern:

  • beforeWrite()- Ändert einen Schreibvorgang, bevor er stattfindet

  • afterRead()- Ändert die Ergebnisse eines Lesevorgangs, nachdem er ausgeführt wurde

Bei einigen Operationen (wie Artikelaktualisierungen) wird sowohl ein Schreib- als auch ein Lesevorgang ausgeführt, sodass beide Hook-Methoden aufgerufen werden.

Wie werden Erweiterungen geladen

Erweiterungen werden in der Reihenfolge geladen, die Sie im erweiterten Client Builder angegeben haben. Die Ladereihenfolge kann wichtig sein, da eine Erweiterung auf Werte reagieren kann, die durch eine vorherige Erweiterung transformiert wurden.

Standardmäßig lädt der erweiterte Client zwei Erweiterungen:

Sie können das Standardverhalten mit dem erweiterten Client Builder überschreiben und jede Erweiterung laden. Sie können auch keine angeben, wenn Sie die Standarderweiterungen nicht verwenden möchten.

Wichtig

Wenn Sie Ihre eigenen Erweiterungen laden, lädt der erweiterte Client keine Standarderweiterungen. Wenn Sie das Verhalten einer der Standarderweiterungen verwenden möchten, müssen Sie sie explizit zur Liste der Erweiterungen hinzufügen.

Das folgende Beispiel zeigt, wie eine benutzerdefinierte Erweiterung geladen wird, die verifyChecksumExtension nach dem benannt istVersionedRecordExtension. Die AtomicCounterExtension ist in diesem Beispiel nicht geladen.

DynamoDbEnhancedClientExtension versionedRecordExtension = VersionedRecordExtension.builder().build(); DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(dynamoDbClient) .extensions(versionedRecordExtension, verifyChecksumExtension) .build();

Verfügbare Erweiterungsdetails und Konfiguration

Die folgenden Abschnitte enthalten detaillierte Informationen zu jeder verfügbaren Erweiterung im SDK.

Implementieren Sie optimistisches Sperren mit dem VersionedRecordExtension

Die VersionedRecordExtension Erweiterung ermöglicht optimistisches Sperren, indem die Versionsnummer eines Elements beim Schreiben von Elementen in die Datenbank erhöht und nachverfolgt wird. Jedem Schreibvorgang wird eine Bedingung hinzugefügt, die dazu führt, dass der Schreibvorgang fehlschlägt, wenn die Versionsnummer des tatsächlich persistenten Elements nicht dem Wert entspricht, den die Anwendung zuletzt gelesen hat.

Konfiguration

Um anzugeben, welches Attribut verwendet werden soll, um die Versionsnummer des Elements nachzuverfolgen, kennzeichnen Sie ein numerisches Attribut im Tabellenschema.

Der folgende Codeausschnitt gibt an, dass das version Attribut die Versionsnummer des Artikels enthalten soll.

@DynamoDbVersionAttribute public Integer getVersion() {...}; public void setVersion(Integer version) {...};

Der entsprechende Ansatz für ein statisches Tabellenschema wird im folgenden Codeausschnitt dargestellt.

.addAttribute(Integer.class, a -> a.name("version") .getter(Customer::getVersion) .setter(Customer::setVersion) // Apply the 'version' tag to the attribute. .tags(VersionedRecordExtension.AttributeTags.versionAttribute())

Funktionsweise

Das optimistische Sperren mit dem VersionedRecordExtension hat folgende Auswirkungen auf diese DynamoDbEnhancedClient und DynamoDbTable Methoden:

putItem

Neuen Elementen wird der ursprüngliche Versionswert 0 zugewiesen. Dies kann mit konfiguriert werden@DynamoDbVersionAttribute(startAt = X).

updateItem

Wenn Sie ein Element abrufen, eine oder mehrere seiner Eigenschaften aktualisieren und versuchen, die Änderungen zu speichern, ist der Vorgang nur erfolgreich, wenn die Versionsnummer auf der Client- und der Serverseite übereinstimmen.

Bei Erfolg wird die Versionsnummer automatisch um 1 erhöht. Dies kann mit @DynamoDbVersionAttribute(incrementBy = X) konfiguriert werden.

deleteItem

Die DynamoDbVersionAttribute Anmerkung hat keine Auswirkung. Sie müssen beim Löschen eines Elements manuell Bedingungsausdrücke hinzufügen.

Im folgenden Beispiel wird ein bedingter Ausdruck hinzugefügt, um sicherzustellen, dass es sich bei dem gelöschten Element auch um das gelesene Element handelt. Im folgenden Beispiel recordVersion ist das Attribut der Bean mit @DynamoDbVersionAttribute annotiert.

// 1. Read the item and get its current version. Customer item = customerTable.getItem(Key.builder().partitionValue("someId").build()); // `recordVersion` is the bean's attribute that is annotated with `@DynamoDbVersionAttribute`. AttributeValue currentVersion = item.getRecordVersion(); // 2. Create conditional delete with the `currentVersion` value. DeleteItemEnhancedRequest deleteItemRequest = DeleteItemEnhancedRequest.builder() .key(KEY) .conditionExpression(Expression.builder() .expression("recordVersion = :current_version_value") .putExpressionValue(":current_version_value", currentVersion) .build()).build(); customerTable.deleteItem(deleteItemRequest);
transactWriteItems
  • addPutItem: Diese Methode hat das gleiche Verhalten wieputItem.

  • addUpdateItem: Diese Methode hat das gleiche Verhalten wieupdateItem.

  • addDeleteItem: Diese Methode hat das gleiche Verhalten wiedeleteItem.

batchWriteItem
  • addPutItem: Diese Methode hat das gleiche Verhalten wieputItem.

  • addDeleteItem: Diese Methode hat das gleiche Verhalten wiedeleteItem.

Anmerkung

Globale DynamoDB-Tabellen verwenden einen Abgleich zwischen gleichzeitigen Aktualisierungen, bei dem DynamoDB sich nach besten Kräften bemüht, den letzten Writer zu ermitteln. Wenn Sie globale Tabellen verwenden, bedeutet diese „Last Writer gewinnt“ -Richtlinie, dass Sperrstrategien möglicherweise nicht wie erwartet funktionieren, da alle Replikate letztendlich auf der Grundlage des von DynamoDB bestimmten letzten Schreibvorgangs konvergieren.

Wie deaktiviere ich

Verwenden Sie die @DynamoDbVersionAttribute Anmerkung nicht, um das optimistische Sperren zu deaktivieren.

Implementieren Sie Zähler mit dem AtomicCounterExtension

Die AtomicCounterExtension Erweiterung erhöht jedes Mal, wenn ein Datensatz in die Datenbank geschrieben wird, ein mit Tags versehenes numerisches Attribut. Sie können Start- und Inkrementwerte angeben. Wenn keine Werte angegeben sind, wird der Startwert auf 0 gesetzt und der Wert des Attributs wird um 1 erhöht.

Konfiguration

Um anzugeben, welches Attribut ein Zähler ist, kennzeichnen Sie ein Attribut vom Typ Long im Tabellenschema.

Der folgende Ausschnitt zeigt die Verwendung der standardmäßigen Start- und Inkrementwerte für das Attribut. counter

@DynamoDbAtomicCounter public Long getCounter() {...}; public void setCounter(Long counter) {...};

Der Ansatz eines statischen Tabellenschemas wird im folgenden Codeausschnitt dargestellt. Die Atomic Counter Extension verwendet einen Startwert von 10 und erhöht den Wert jedes Mal, wenn der Datensatz geschrieben wird, um 5.

.addAttribute(Integer.class, a -> a.name("counter") .getter(Customer::getCounter) .setter(Customer::setCounter) // Apply the 'atomicCounter' tag to the attribute with start and increment values. .tags(StaticAttributeTags.atomicCounter(10L, 5L))

Fügen Sie Zeitstempel hinzu mit AutoGeneratedTimestampRecordExtension

Die AutoGeneratedTimestampRecordExtension Erweiterung aktualisiert jedes Mal, wenn das Element erfolgreich in die Datenbank geschrieben wurde, automatisch markierte Attribute des Typs Instant mit einem aktuellen Zeitstempel. Diese Erweiterung ist standardmäßig nicht geladen.

Konfiguration

Um anzugeben, welches Attribut mit dem aktuellen Zeitstempel aktualisiert werden soll, kennzeichnen Sie das Instant Attribut im Tabellenschema.

Das lastUpdate Attribut ist das Ziel des Verhaltens der Erweiterung im folgenden Codeausschnitt. Beachten Sie die Anforderung, dass das Attribut ein Instant Typ sein muss.

@DynamoDbAutoGeneratedTimestampAttribute public Instant getLastUpdate() {...} public void setLastUpdate(Instant lastUpdate) {...}

Der entsprechende Ansatz für ein statisches Tabellenschema wird im folgenden Codeausschnitt dargestellt.

.addAttribute(Instant.class, a -> a.name("lastUpdate") .getter(Customer::getLastUpdate) .setter(Customer::setLastUpdate) // Applying the 'autoGeneratedTimestamp' tag to the attribute. .tags(AutoGeneratedTimestampRecordExtension.AttributeTags.autoGeneratedTimestampAttribute())

Generieren Sie eine UUID mit dem AutoGeneratedUuidExtension

Die AutoGeneratedUuidExtension Erweiterung generiert eine eindeutige UUID (Universally Unique Identifier) für ein Attribut, wenn ein neuer Datensatz in die Datenbank geschrieben wird. Verwendet die Java-JDK-Methode UUID.randomUUID () und gilt für Typattribute. java.lang.String Diese Erweiterung wird standardmäßig nicht geladen.

Konfiguration

Das uniqueId Attribut ist das Ziel des Verhaltens der Erweiterung im folgenden Codeausschnitt.

@AutoGeneratedUuidExtension public String getUniqueId() {...} public void setUniqueId(String uniqueId) {...}

Der entsprechende Ansatz für ein statisches Tabellenschema wird im folgenden Codeausschnitt dargestellt.

.addAttribute(String.class, a -> a.name("uniqueId") .getter(Customer::getUniqueId) .setter(Customer::setUniqueId) // Applying the 'autoGeneratedUuid' tag to the attribute. .tags(AutoGeneratedUuidExtension.AttributeTags.autoGeneratedUuidAttribute())

Wenn Sie möchten, dass die Erweiterung die UUID nur für putItem Methoden und nicht für Methoden auffüllt, fügen Sie die Anmerkung zum updateItem Aktualisierungsverhalten hinzu, wie im folgenden Codeausschnitt gezeigt.

@AutoGeneratedUuidExtension @DynamoDbUpdateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS) public String getUniqueId() {...} public void setUniqueId(String uniqueId) {...}

Wenn Sie den Ansatz eines statischen Tabellenschemas verwenden, verwenden Sie den folgenden äquivalenten Code.

.addAttribute(String.class, a -> a.name("uniqueId") .getter(Customer::getUniqueId) .setter(Customer::setUniqueId) // Applying the 'autoGeneratedUuid' tag to the attribute. .tags(AutoGeneratedUuidExtension.AttributeTags.autoGeneratedUuidAttribute(), StaticAttributeTags.updateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS))