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 unikCustomerId
.ProductCatalog
— Tabel ini menyimpan detail seperti harga dan ketersediaan produk yang dijual di marketplace. Kunci primernya adalah pengidentifikasi unikProductId
.Orders
— Tabel ini menyimpan detail pesanan dari marketplace. Kunci primernya adalah pengidentifikasi unikOrderId
.
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:
Tentukan apakah ID pelanggan valid.
Pastikan produk
IN_STOCK
, dan perbarui status produk menjadiSOLD
.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()); }