Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Esempio di transazioni di DynamoDB
Come esempio di una situazione in cui le transazioni Amazon DynamoDB possono essere utili, si consideri questa applicazione Java di esempio per un marketplace online.
L'applicazione ha tre tabelle DynamoDB nel backend:
Customers
: questa tabella archivia i dettagli sui clienti del marketplace. La sua chiave primaria è un identificatore univocoCustomerId
.ProductCatalog
: questa tabella archivia dettagli quali prezzo e disponibilità dei prodotti in vendita nel marketplace. La sua chiave primaria è un identificatore univocoProductId
.Orders
: questa tabella archivia i dettagli sugli ordini del marketplace. La sua chiave primaria è un identificatore univocoOrderId
.
Come effettuare un ordine
I seguenti frammenti di codice illustrano come utilizzare le transazioni DynamoDB per coordinare i vari passaggi necessari per creare ed elaborare un ordine. L'utilizzo di una singola all-or-nothing operazione garantisce che, se una parte della transazione fallisce, non vengano eseguite azioni nella transazione e non vengano apportate modifiche.
In questo esempio, si configura un ordine da un cliente il cui customerId
è 09e8e9c8-ec48
. Si esegue quindi come una singola transazione utilizzando il seguente flusso di lavoro semplice di elaborazione degli ordini:
Determinare che l'ID cliente sia valido.
Assicurati che il prodotto sia
IN_STOCK
e aggiornare lo stato del prodotto inSOLD
.Assicurati che l'ordine non esista già e creare l'ordine.
Convalida del cliente
Per prima cosa, definire un'azione per verificare che un cliente con customerId
uguale a 09e8e9c8-ec48
esista nella tabella dei clienti.
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 + ")");
Aggiornamento dello stato dei prodotti
Quindi, definire un'operazione per aggiornare lo stato del prodotto in SOLD
se la condizione in cui lo stato del prodotto è attualmente impostato su IN_STOCK
è true
. La configurazione del parametro ReturnValuesOnConditionCheckFailure
restituisce l'elemento se l'attributo dello stato del prodotto dell'elemento non era uguale a IN_STOCK
.
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);
Creazione dell'ordine
Infine, creare l'ordine se un ordine con quell'OrderId
non esiste già.
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 + ")");
Esecuzione della transazione
L'esempio seguente illustra come eseguire le azioni definite in precedenza come singola all-or-nothing operazione.
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()); }
Lettura dei dettagli dell'ordine
L'esempio seguente mostra come leggere l'ordine completato in modo transazionale attraverso le tabelle Orders
e ProductCatalog
.
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()); }