-1

I am new to DynamoDB and working on a dynamo project. I am trying to update the item amount in a transaction with condition if_not_exists() with TransactionWriteRequest in DynamoDB Mapper.

As per the Doc, transactionWriteRequest.updateItem() takes DynamoDBTransactionWriteExpression which doesn't have any UpdateExpression. Class definition is attached bellow.,

Wanted to know How can i provide the if_not_exists() in DynamoDBTransactionWriteExpression to update the item in a transaction. Or there is no way to do this in a transactionWrite.

Please help here.

Thanks in advance

Shailendra
  • 528
  • 2
  • 10
  • 21
  • Before I dig into this more, can you tell me why you are using a Transaction to update an item and not just using `UpdateItem`? – Leeroy Hannigan Nov 24 '22 at 20:38
  • Its not just single item update, TranactionRequest contains few PutItem() and one updateItem(). It's not only one update item. – Shailendra Nov 25 '22 at 02:24

2 Answers2

1

Judging from the snippet you shared it seems you are using Java SDK v1. Below is a code snippet which has 1 PutItem and 1 UpdateItem combined in a single TransactWrite request.

    AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();

    final String ORDER_TABLE_NAME = "test1";

    /*
    Update Item with condition
     */

    HashMap<String,AttributeValue> myPk =
            new HashMap<String,AttributeValue>();

    myPk.put("pk", new AttributeValue("pkValue1"));

    Map<String, AttributeValue> expressionAttributeValues = new HashMap<>();
    expressionAttributeValues.put(":new_status", new AttributeValue("SOLD"));
    
    Update markItemSold = new Update()
            .withTableName(ORDER_TABLE_NAME)
            .withKey(myPk)
            .withUpdateExpression("SET ProductStatus = if_not_exists(createdAt, :new_status)")
            .withExpressionAttributeValues(expressionAttributeValues)
            .withReturnValuesOnConditionCheckFailure(ReturnValuesOnConditionCheckFailure.ALL_OLD);

      /*
    Put Item
     */

    HashMap<String, AttributeValue> orderItem = new HashMap<>();
    orderItem.put("pk", new AttributeValue("pkValue2"));
    orderItem.put("OrderTotal", new AttributeValue("100"));

    Put createOrder = new Put()
            .withTableName(ORDER_TABLE_NAME)
            .withItem(orderItem)
            .withReturnValuesOnConditionCheckFailure(ReturnValuesOnConditionCheckFailure.ALL_OLD);

      /*
       Transaction
     */

    Collection<TransactWriteItem> actions = Arrays.asList(
            new TransactWriteItem().withUpdate(markItemSold),
            new TransactWriteItem().withPut(createOrder));

    TransactWriteItemsRequest placeOrderTransaction = new TransactWriteItemsRequest()
            .withTransactItems(actions)
            .withReturnConsumedCapacity(ReturnConsumedCapacity.TOTAL);

    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());
    } catch (AmazonServiceException e){
        System.out.println(e.getMessage());
    }
Leeroy Hannigan
  • 11,409
  • 3
  • 14
  • 31
0

With the v2 version of the SDK you can do it like this

    var table =
            enhancedClient.table(<table name>, TableSchema.fromClass(DynamoEntity.class));

    var transactWriteItemsEnhancedRequest = TransactWriteItemsEnhancedRequest
            .builder()
            .addUpdateItem(table,
                    TransactUpdateItemEnhancedRequest.builder(LoadTestEntity.class)
                            .item(<entity>)
                            .conditionExpression(Expression.builder().expression("attribute_not_exists(ID)").build())
                            .build())
            .build();

    enhancedClient.transactWriteItems(transactWriteItemsEnhancedRequest);

You might need to play around with the expression builder, I haven't tested it.

Borislav Stoilov
  • 3,247
  • 2
  • 21
  • 46