DynamoDB-Transaktionen-Beispiel - Amazon-DynamoDB

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.

DynamoDB-Transaktionen-Beispiel

Als Beispiel für eine Situation, in der Amazon DynamoDB Transactions nützlich sein können, betrachten Sie diese Java-Beispielanwendung für eine Online-Marketplace-Site.

Die Anwendung verfügt über drei DynamoDB-Tabellen im Backend:

  • Customers – In dieser Tabelle werden Details zu den Marketplace-Kunden gespeichert. Der Primärschlüssel ist ein CustomerId eine eindeutige ID.

  • ProductCatalog – In dieser Tabelle werden Details wie Preis und Verfügbarkeit zu den Produkten gespeichert, die auf der Marketplace-Site zum Verkauf angeboten werden. Der Primärschlüssel ist ein ProductId eine eindeutige ID.

  • Orders – In dieser Tabelle werden Details zu Bestellungen von der Marketplace-Site gespeichert. Der Primärschlüssel ist ein OrderId eine eindeutige ID.

Bestellung

Die folgenden Codeausschnitte veranschaulichen, wie DynamoDB-Transaktionen verwendet werden, um die verschiedenen Schritte zu koordinieren, die zum Erstellen und Verarbeiten eines Auftrags erforderlich sind. Wenn ein Teil der Transaktion fehlschlägt, wird sichergestellt, dass keine Aktionen in der Transaktion ausgeführt werden und keine Änderungen vorgenommen werden.

In diesem Beispiel richten Sie einen Auftrag eines Kunden ein, dessen customerId 09e8e9c8-ec48 ist. Anschließend führen Sie sie als einzelne Transaktion aus, indem Sie den folgenden einfachen Workflow für die Auftragsverarbeitung verwenden:

  1. Stellen Sie sicher, dass die Kundennummer gültig ist.

  2. Stellen Sie sicher, dass das Produkt IN_STOCK ist und aktualisieren Sie den Produktstatus auf SOLD.

  3. Stellen Sie sicher, dass die Bestellung noch nicht vorhanden ist, und erstellen Sie den Auftrag.

Kunden validieren

Definieren Sie zunächst eine Aktion, um zu überprüfen, ob ein Kunde mit customerId gleich 09e8e9c8-ec48 in der Kundentabelle vorhanden ist.

final String CUSTOMER_TABLE_NAME = "Customers"; final String CUSTOMER_PARTITION_KEY = "CustomerId"; final String customerId = "09e8e9c8-ec48"; final HashMap<String, AttributeValue> customerItemKey = new HashMap<>(); customerItemKey.put(CUSTOMER_PARTITION_KEY, new AttributeValue(customerId)); ConditionCheck checkCustomerValid = new ConditionCheck() .withTableName(CUSTOMER_TABLE_NAME) .withKey(customerItemKey) .withConditionExpression("attribute_exists(" + CUSTOMER_PARTITION_KEY + ")");

Aktualisieren des Produktstatus

Definieren Sie als Nächstes eine Aktion, um den Produktstatus auf SOLD zu aktualisieren, wenn die Bedingung, auf die der Produktstatus als IN_STOCKderzeit festgelegt ist, true ist. Das Festlegen des ReturnValuesOnConditionCheckFailure-Parameters gibt den Artikel zurück, wenn das Produktstatusattribut des Artikels nicht gleich IN_STOCK war.

final String PRODUCT_TABLE_NAME = "ProductCatalog"; final String PRODUCT_PARTITION_KEY = "ProductId"; HashMap<String, AttributeValue> productItemKey = new HashMap<>(); productItemKey.put(PRODUCT_PARTITION_KEY, new AttributeValue(productKey)); Map<String, AttributeValue> expressionAttributeValues = new HashMap<>(); expressionAttributeValues.put(":new_status", new AttributeValue("SOLD")); expressionAttributeValues.put(":expected_status", new AttributeValue("IN_STOCK")); Update markItemSold = new Update() .withTableName(PRODUCT_TABLE_NAME) .withKey(productItemKey) .withUpdateExpression("SET ProductStatus = :new_status") .withExpressionAttributeValues(expressionAttributeValues) .withConditionExpression("ProductStatus = :expected_status") .withReturnValuesOnConditionCheckFailure(ReturnValuesOnConditionCheckFailure.ALL_OLD);

Bestellung erstellen

Schließlich erstellen Sie die Bestellung, solange eine Bestellung mit diesem OrderId nicht bereits existiert.

final String ORDER_PARTITION_KEY = "OrderId"; final String ORDER_TABLE_NAME = "Orders"; HashMap<String, AttributeValue> orderItem = new HashMap<>(); orderItem.put(ORDER_PARTITION_KEY, new AttributeValue(orderId)); orderItem.put(PRODUCT_PARTITION_KEY, new AttributeValue(productKey)); orderItem.put(CUSTOMER_PARTITION_KEY, new AttributeValue(customerId)); orderItem.put("OrderStatus", new AttributeValue("CONFIRMED")); orderItem.put("OrderTotal", new AttributeValue("100")); Put createOrder = new Put() .withTableName(ORDER_TABLE_NAME) .withItem(orderItem) .withReturnValuesOnConditionCheckFailure(ReturnValuesOnConditionCheckFailure.ALL_OLD) .withConditionExpression("attribute_not_exists(" + ORDER_PARTITION_KEY + ")");

Ausführen der Transaktion

Im folgenden Beispiel wird veranschaulicht, wie die zuvor als einzelner Alles-oder-Nichts-Vorgang definierten Aktionen ausgeführt werden.

Collection<TransactWriteItem> actions = Arrays.asList( new TransactWriteItem().withConditionCheck(checkCustomerValid), new TransactWriteItem().withUpdate(markItemSold), new TransactWriteItem().withPut(createOrder)); TransactWriteItemsRequest placeOrderTransaction = new TransactWriteItemsRequest() .withTransactItems(actions) .withReturnConsumedCapacity(ReturnConsumedCapacity.TOTAL); // Run the transaction and process the result. try { client.transactWriteItems(placeOrderTransaction); System.out.println("Transaction Successful"); } catch (ResourceNotFoundException rnf) { System.err.println("One of the table involved in the transaction is not found" + rnf.getMessage()); } catch (InternalServerErrorException ise) { System.err.println("Internal Server Error" + ise.getMessage()); } catch (TransactionCanceledException tce) { System.out.println("Transaction Canceled " + tce.getMessage()); }

Lesen der Bestelldetails

Das folgende Beispiel zeigt, wie der abgeschlossene Auftrag transaktional über die Orders- und ProductCatalog-Tabellen gelesen wird.

HashMap<String, AttributeValue> productItemKey = new HashMap<>(); productItemKey.put(PRODUCT_PARTITION_KEY, new AttributeValue(productKey)); HashMap<String, AttributeValue> orderKey = new HashMap<>(); orderKey.put(ORDER_PARTITION_KEY, new AttributeValue(orderId)); Get readProductSold = new Get() .withTableName(PRODUCT_TABLE_NAME) .withKey(productItemKey); Get readCreatedOrder = new Get() .withTableName(ORDER_TABLE_NAME) .withKey(orderKey); Collection<TransactGetItem> getActions = Arrays.asList( new TransactGetItem().withGet(readProductSold), new TransactGetItem().withGet(readCreatedOrder)); TransactGetItemsRequest readCompletedOrder = new TransactGetItemsRequest() .withTransactItems(getActions) .withReturnConsumedCapacity(ReturnConsumedCapacity.TOTAL); // Run the transaction and process the result. try { TransactGetItemsResult result = client.transactGetItems(readCompletedOrder); System.out.println(result.getResponses()); } catch (ResourceNotFoundException rnf) { System.err.println("One of the table involved in the transaction is not found" + rnf.getMessage()); } catch (InternalServerErrorException ise) { System.err.println("Internal Server Error" + ise.getMessage()); } catch (TransactionCanceledException tce) { System.err.println("Transaction Canceled" + tce.getMessage()); }

Weitere Beispiele