Home > Software engineering >  BatchDelete is not deleting all value in list
BatchDelete is not deleting all value in list

Time:01-04

Trying to delete multiple row of DynamoDB.

Querying only on one table of DynamoDB.On basis the of Partition key, its returning 2 values as output, which is save in list.

enter image description here Now after deleting this value using BatchDelete only first element get deleted. Sometimes on random basis second value also get deleted but that was not happened every time.

     DynamoDBQueryExpression<Abc> queryExpression = new DynamoDBQueryExpression<Abc>()
                    .withHashKeyValues(abc);  
         
        List<Abc> xyz = dynamoDBMapper.query(Abc.class,queryExpression);
//xyz has size 2

        dynamoDBMapper.batchDelete(xyz);

Should I use sleep or is there any other way.

CodePudding user response:

If you look at Java V1 here:

enter image description here

I strongly recommend that you upgrade to the AWS SDK for Java v2 API.

When working with Java V2 and DynamoDB, its recommended that you use the Enhanced Client, which is documented in the Java V2 Developer Guide here:

Mapping items in DynamoDB tables

To use the Enhanced Client to delete multiple items, you can use this Java code:

package com.example.dynamodb;

// snippet-start:[dynamodb.java2.mapping.batchdelete.import]
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.model.BatchWriteItemEnhancedRequest;
import software.amazon.awssdk.enhanced.dynamodb.model.DeleteItemEnhancedRequest;
import software.amazon.awssdk.enhanced.dynamodb.model.WriteBatch;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
// snippet-end:[dynamodb.java2.mapping.batchdelete.import]

/*
 * Before running this code example, create an Amazon DynamoDB table named Customer with these columns:
 *   - id - the id of the record that is the key
 *   - custName - the customer name
 *   - email - the email value
 *   - registrationDate - an instant value when the item was added to the table
 *
 * Also, ensure that you have set up your development environment, including your credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class EnhancedBatchDeleteItems {

    public static void main(String[] args) {

        ProfileCredentialsProvider credentialsProvider = ProfileCredentialsProvider.create();
        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
            .region(region)
            .credentialsProvider(credentialsProvider)
            .build();

        DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
            .dynamoDbClient(ddb)
            .build();
        deleteBatchRecords(enhancedClient);
        ddb.close();
    }

    // snippet-start:[dynamodb.java2.mapping.batchdelete.main]
    public static void deleteBatchRecords(DynamoDbEnhancedClient enhancedClient) {
        try {
            DynamoDbTable<Customer> mappedTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
            Key key1 = Key.builder()
                .partitionValue("id110")
                .build();

            Key key2 = Key.builder()
                .partitionValue("id120")
                .build();

            BatchWriteItemEnhancedRequest request = BatchWriteItemEnhancedRequest.builder()
                .writeBatches(WriteBatch.builder(Customer.class)
                    .mappedTableResource(mappedTable)
                    .addDeleteItem(DeleteItemEnhancedRequest.builder()
                        .key(key1)
                        .build())
                    .build(),
                WriteBatch.builder(Customer.class)
                    .mappedTableResource(mappedTable)
                    .addDeleteItem(DeleteItemEnhancedRequest.builder()
                        .key(key2)
                        .build())
                    .build())
                .build();

            // Delete these two items from the table.
            enhancedClient.batchWriteItem(request);
            System.out.println("Records deleted");

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
    // snippet-end:[dynamodb.java2.mapping.batchdelete.main]
}

You can find this example and other Java v2 DynamoDB examples in AWS Code Example Github.

CodePudding user response:

I do not see any issue with your code, I have tested similar and works for me with no issue. My first suggestion would be to ensure you wrap your code in a try/catch block:

        try {

            DynamoDBMapper mapper = new DynamoDBMapper(client);

            Reply key = new Reply();
            key.setPk("1");

            DynamoDBQueryExpression<Reply> queryExpression = new DynamoDBQueryExpression<Reply>()
                    .withHashKeyValues(key)
                    .withReturnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                    .withScanIndexForward(false);

            List<Reply> latestReplies = mapper.query(Reply.class, queryExpression);
            
            // Log keys here to be sure you are deleting the correct item
            for (Reply c: latestReplies) {
                System.out.println(c.getPk());
            }

            mapper.batchDelete(latestReplies);

        } catch (Throwable t) {
            System.err.println("Error running: "   t);
            t.printStackTrace();
        }

I would suggest that you implement some logging, just to be sure that the items you read are the ones you expected to be deleted.

It may also be worth enabling CloudTrail Dataplane Logs which will allow you to see all the dataplane events being executed on the table.

You may also enable HTTP wire logging to provide you another level of logging, however, this is not advised for production workloads as the logging is quite verbose.

  • Related