Contoh DynamoDB transactions - Amazon DynamoDB

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Contoh DynamoDB transactions

Sebagai contoh situasi di mana Amazon DynamoDB transactions dapat berguna, pertimbangkan contoh aplikasi Java untuk marketplace online ini.

Aplikasi ini memiliki tiga tabel DynamoDB di backend:

  • Customers — Tabel ini menyimpan detail tentang pelanggan marketplace. Kunci primernya adalah pengidentifikasi unik CustomerId.

  • ProductCatalog — Tabel ini menyimpan detail seperti harga dan ketersediaan produk yang dijual di marketplace. Kunci primernya adalah pengidentifikasi unik ProductId.

  • Orders — Tabel ini menyimpan detail pesanan dari marketplace. Kunci primernya adalah pengidentifikasi unik OrderId.

Membuat pesanan

Potongan kode berikut menggambarkan cara menggunakan DynamoDB transaction untuk mengoordinasikan beberapa langkah yang diperlukan untuk membuat dan memproses pesanan. Menggunakan satu all-or-nothing operasi memastikan bahwa jika ada bagian dari transaksi yang gagal, tidak ada tindakan dalam transaksi yang dijalankan dan tidak ada perubahan yang dilakukan.

Dalam contoh ini, Anda menyiapkan pesanan dari pelanggan yang customerId adalah 09e8e9c8-ec48. Anda kemudian menjalankannya sebagai satu transaksi menggunakan alur kerja pemrosesan pesanan sederhana berikut:

  1. Tentukan apakah ID pelanggan valid.

  2. Pastikan produk IN_STOCK, dan perbarui status produk menjadi SOLD.

  3. Pastikan pesanan belum ada, lalu buat pesanan.

Memvalidasi pelanggan

Pertama, tentukan tindakan untuk memverifikasi bahwa pelanggan dengan customerId sama dengan 09e8e9c8-ec48 ada di tabel pelanggan.

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 + ")");

Memperbarui status produk

Selanjutnya, tentukan tindakan untuk memperbarui status produk menjadi SOLD jika kondisi status produk saat ini diatur ke IN_STOCK true. Mengatur parameter ReturnValuesOnConditionCheckFailure akan mengembalikan item jika atribut status produk item tidak sama dengan 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);

Membuat pesanan

Terakhir, buat pesanan selama pesanan dengan OrderId tersebut belum ada.

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 + ")");

Menjalankan transaksi

Contoh berikut menggambarkan bagaimana menjalankan tindakan yang didefinisikan sebelumnya sebagai all-or-nothing operasi tunggal.

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()); }

Membaca detail pesanan

Contoh berikut menunjukkan cara membaca pesanan yang telah selesai secara transaksional di seluruh tabel Orders dan 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()); }