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 einCustomerId
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 einProductId
eine eindeutige ID.Orders
– In dieser Tabelle werden Details zu Bestellungen von der Marketplace-Site gespeichert. Der Primärschlüssel ist einOrderId
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. Durch die Verwendung eines einzigen all-or-nothing Vorgangs wird sichergestellt, dass, falls ein Teil der Transaktion fehlschlägt, keine Aktionen in der Transaktion ausgeführt 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:
Stellen Sie sicher, dass die Kundennummer gültig ist.
Stellen Sie sicher, dass das Produkt
IN_STOCK
ist und aktualisieren Sie den Produktstatus aufSOLD
.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_STOCK
derzeit 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
Das folgende Beispiel zeigt, wie die zuvor als einzelne all-or-nothing Operation 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()); }