Skip to content

Commit e5a9546

Browse files
committed
Optimistic locking for delete scenario with DeleteItemEnhancedRequest and TransactWriteItemsEnhancedRequest
1 parent d45479f commit e5a9546

File tree

17 files changed

+815
-688
lines changed

17 files changed

+815
-688
lines changed

.idea/codeStyles/Project.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

services-custom/dynamodb-enhanced/src/it/java/software/amazon/awssdk/enhanced/dynamodb/AsyncCrudWithResponseIntegrationTest.java

Lines changed: 11 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ public class AsyncCrudWithResponseIntegrationTest extends DynamoDbEnhancedIntegr
6464
@BeforeClass
6565
public static void beforeClass() {
6666
dynamoDbClient = createAsyncDynamoDbClient();
67-
enhancedClient = DynamoDbEnhancedAsyncClient.builder().dynamoDbClient(dynamoDbClient).build();
67+
enhancedClient = DynamoDbEnhancedAsyncClient.builder()
68+
.dynamoDbClient(dynamoDbClient)
69+
.extensions(VersionedRecordExtension.builder().build())
70+
.build();
6871
mappedTable = enhancedClient.table(TABLE_NAME, TABLE_SCHEMA);
6972
mappedTable.createTable(r -> r.localSecondaryIndices(LOCAL_SECONDARY_INDEX)).join();
7073
versionedRecordTable = enhancedClient.table(TABLE_NAME, VERSIONED_RECORD_TABLE_SCHEMA);
@@ -353,8 +356,7 @@ public void getItem_withoutReturnConsumedCapacity() {
353356
}
354357

355358
@Test
356-
public void transactWriteItemsWithoutVersion_andOptimisticDeleteEnabled_shouldSucceed() {
357-
initEnhancedClient(true);
359+
public void transactWriteItems_recordWithoutVersion_andOptimisticLockingOnDeleteOnDelete_shouldSucceed() {
358360
Record originalItem = new Record().setId("123").setSort(10).setStringAttribute("Original Item");
359361
Key recordKey = Key.builder().partitionValue(originalItem.getId()).sortValue(originalItem.getSort()).build();
360362

@@ -377,33 +379,7 @@ public void transactWriteItemsWithoutVersion_andOptimisticDeleteEnabled_shouldSu
377379
}
378380

379381
@Test
380-
public void transactWriteItemsWithoutVersion_andOptimisticDeleteDisabled_shouldSucceed() {
381-
initEnhancedClient(false);
382-
383-
Record originalItem = new Record().setId("123").setSort(10).setStringAttribute("Original Item");
384-
Key recordKey = Key.builder().partitionValue(originalItem.getId()).sortValue(originalItem.getSort()).build();
385-
386-
// Put the item
387-
mappedTable.putItem(originalItem).join();
388-
389-
// Retrieve the item, modify it separately and update it, which will increment the version
390-
Record savedItem = mappedTable.getItem(r -> r.key(recordKey)).join();
391-
savedItem.setStringAttribute("Updated Item");
392-
mappedTable.updateItem(savedItem).join();
393-
394-
// Get the updated item and try to delete it
395-
Record updatedItem = mappedTable.getItem(r -> r.key(recordKey)).join();
396-
enhancedClient.transactWriteItems(TransactWriteItemsEnhancedRequest.builder()
397-
.addDeleteItem(mappedTable, updatedItem)
398-
.build()).join();
399-
400-
Record deletedItem = mappedTable.getItem(r -> r.key(recordKey)).join();
401-
assertThat(deletedItem).isNull();
402-
}
403-
404-
@Test
405-
public void transactWriteItemsWithVersion_andOptimisticDeleteEnabled_ifVersionMatch_shouldSucceed() {
406-
initEnhancedClient(true);
382+
public void transactWriteItems_recordWithVersion_andOptimisticLockingOnDelete_ifVersionMatch_shouldSucceed() {
407383
VersionedRecord originalItem = new VersionedRecord().setId("123").setSort(10).setStringAttribute("Original Item");
408384
Key recordKey = Key.builder().partitionValue(originalItem.getId()).sortValue(originalItem.getSort()).build();
409385

@@ -418,18 +394,15 @@ public void transactWriteItemsWithVersion_andOptimisticDeleteEnabled_ifVersionMa
418394
// Get the updated item and try to delete it
419395
VersionedRecord updatedItem = versionedRecordTable.getItem(r -> r.key(recordKey)).join();
420396
enhancedClient.transactWriteItems(TransactWriteItemsEnhancedRequest.builder()
421-
.addDeleteItem(
422-
versionedRecordTable,
423-
updatedItem)
397+
.addDeleteItem(versionedRecordTable, updatedItem)
424398
.build()).join();
425399

426400
VersionedRecord deletedItem = versionedRecordTable.getItem(r -> r.key(recordKey)).join();
427401
assertThat(deletedItem).isNull();
428402
}
429403

430404
@Test
431-
public void transactWriteItemsWithVersion_andOptimisticDeleteEnabled_ifVersionMismatch_shouldFail() {
432-
initEnhancedClient(true);
405+
public void transactWriteItems_recordWithVersion_andOptimisticLockingOnDelete_ifVersionMismatch_shouldFail() {
433406
VersionedRecord originalItem = new VersionedRecord().setId("123").setSort(10).setStringAttribute("Original Item");
434407
Key recordKey = Key.builder().partitionValue(originalItem.getId()).sortValue(originalItem.getSort()).build();
435408

@@ -463,58 +436,7 @@ public void transactWriteItemsWithVersion_andOptimisticDeleteEnabled_ifVersionMi
463436
}
464437

465438
@Test
466-
public void transactWriteItemsWithVersion_andOptimisticDeleteDisabled_ifVersionMatch_shouldSucceed() {
467-
initEnhancedClient(false);
468-
VersionedRecord originalItem = new VersionedRecord().setId("123").setSort(10).setStringAttribute("Original Item");
469-
Key recordKey = Key.builder().partitionValue(originalItem.getId()).sortValue(originalItem.getSort()).build();
470-
471-
// Put the item
472-
versionedRecordTable.putItem(originalItem).join();
473-
474-
// Retrieve the item, modify it separately and update it, which will increment the version
475-
VersionedRecord savedItem = versionedRecordTable.getItem(r -> r.key(recordKey)).join();
476-
savedItem.setStringAttribute("Updated Item");
477-
versionedRecordTable.updateItem(savedItem).join();
478-
479-
// Get the updated item and try to delete it
480-
VersionedRecord updatedItem = versionedRecordTable.getItem(r -> r.key(recordKey)).join();
481-
enhancedClient.transactWriteItems(TransactWriteItemsEnhancedRequest.builder()
482-
.addDeleteItem(versionedRecordTable,
483-
updatedItem)
484-
.build()).join();
485-
486-
Record deletedItem = mappedTable.getItem(r -> r.key(recordKey)).join();
487-
assertThat(deletedItem).isNull();
488-
}
489-
490-
@Test
491-
public void transactWriteItemsWithVersion_andOptimisticDeleteDisabled_ifVersionMismatch_shouldSucceed() {
492-
initEnhancedClient(false);
493-
VersionedRecord originalItem = new VersionedRecord().setId("123").setSort(10).setStringAttribute("Original Item");
494-
Key recordKey = Key.builder().partitionValue(originalItem.getId()).sortValue(originalItem.getSort()).build();
495-
496-
// Put the item
497-
versionedRecordTable.putItem(originalItem).join();
498-
499-
// Retrieve the item, modify it separately and update it, which will increment the version
500-
VersionedRecord savedItem = versionedRecordTable.getItem(r -> r.key(recordKey)).join();
501-
savedItem.setStringAttribute("Updated Item");
502-
versionedRecordTable.updateItem(savedItem).join();
503-
504-
// Get the updated item and try to delete it
505-
VersionedRecord updatedItem = versionedRecordTable.getItem(r -> r.key(recordKey)).join();
506-
enhancedClient.transactWriteItems(TransactWriteItemsEnhancedRequest.builder()
507-
.addDeleteItem(versionedRecordTable,
508-
updatedItem)
509-
.build()).join();
510-
511-
Record deletedItem = mappedTable.getItem(r -> r.key(recordKey)).join();
512-
assertThat(deletedItem).isNull();
513-
}
514-
515-
@Test
516-
public void deleteRecordWithoutVersion_andOptimisticDeleteEnabled_shouldSucceed() {
517-
initEnhancedClient(true);
439+
public void delete_recordWithoutVersion_andOptimisticLockingOnDelete_shouldSucceed() {
518440
Record originalItem = new Record().setId("123").setSort(10).setStringAttribute("Original Item");
519441
Key recordKey = Key.builder().partitionValue(originalItem.getId()).sortValue(originalItem.getSort()).build();
520442

@@ -535,31 +457,7 @@ public void deleteRecordWithoutVersion_andOptimisticDeleteEnabled_shouldSucceed(
535457
}
536458

537459
@Test
538-
public void deleteRecordWithoutVersion_andOptimisticDeleteDisabled_shouldSucceed() {
539-
initEnhancedClient(false);
540-
541-
Record originalItem = new Record().setId("123").setSort(10).setStringAttribute("Original Item");
542-
Key recordKey = Key.builder().partitionValue(originalItem.getId()).sortValue(originalItem.getSort()).build();
543-
544-
// Put the item
545-
mappedTable.putItem(originalItem).join();
546-
547-
// Retrieve the item, modify it separately and update it, which will increment the version
548-
Record savedItem = mappedTable.getItem(r -> r.key(recordKey)).join();
549-
savedItem.setStringAttribute("Updated Item");
550-
mappedTable.updateItem(savedItem).join();
551-
552-
// Get the updated item and try to delete it
553-
Record updatedItem = mappedTable.getItem(r -> r.key(recordKey)).join();
554-
mappedTable.deleteItem(updatedItem).join();
555-
556-
Record deletedItem = mappedTable.getItem(r -> r.key(recordKey)).join();
557-
assertThat(deletedItem).isNull();
558-
}
559-
560-
@Test
561-
public void deleteRecordWithVersion_andOptimisticDeleteEnabled_ifVersionMatch_shouldSucceed() {
562-
initEnhancedClient(true);
460+
public void delete_recordWithVersion_andOptimisticLockingOnDelete_ifVersionMatch_shouldSucceed() {
563461
VersionedRecord originalItem = new VersionedRecord().setId("123").setSort(10).setStringAttribute("Original Item");
564462
Key recordKey = Key.builder().partitionValue(originalItem.getId()).sortValue(originalItem.getSort()).build();
565463

@@ -580,8 +478,7 @@ public void deleteRecordWithVersion_andOptimisticDeleteEnabled_ifVersionMatch_sh
580478
}
581479

582480
@Test
583-
public void deleteRecordWithVersion_andOptimisticDeleteEnabled_ifVersionMismatch_shouldFail() {
584-
initEnhancedClient(true);
481+
public void delete_recordWithoutVersion_andOptimisticLockingOnDelete_ifVersionMismatch_shouldFail() {
585482
VersionedRecord originalItem = new VersionedRecord().setId("123").setSort(10).setStringAttribute("Original Item");
586483
Key recordKey = Key.builder().partitionValue(originalItem.getId()).sortValue(originalItem.getSort()).build();
587484

@@ -602,67 +499,4 @@ public void deleteRecordWithVersion_andOptimisticDeleteEnabled_ifVersionMismatch
602499
.satisfies(e ->
603500
assertThat(e.getMessage()).contains("The conditional request failed"));
604501
}
605-
606-
@Test
607-
public void deleteRecordWithVersion_andOptimisticDeleteDisabled_ifVersionMatch_shouldSucceed() {
608-
initEnhancedClient(false);
609-
VersionedRecord originalItem = new VersionedRecord().setId("123").setSort(10).setStringAttribute("Original Item");
610-
Key recordKey = Key.builder().partitionValue(originalItem.getId()).sortValue(originalItem.getSort()).build();
611-
612-
// Put the item
613-
versionedRecordTable.putItem(originalItem).join();
614-
615-
// Retrieve the item, modify it separately and update it, which will increment the version
616-
VersionedRecord savedItem = versionedRecordTable.getItem(r -> r.key(recordKey)).join();
617-
savedItem.setStringAttribute("Updated Item");
618-
versionedRecordTable.updateItem(savedItem).join();
619-
620-
// Get the updated item and try to delete it
621-
VersionedRecord updatedItem = versionedRecordTable.getItem(r -> r.key(recordKey)).join();
622-
versionedRecordTable.deleteItem(updatedItem).join();
623-
624-
Record deletedItem = mappedTable.getItem(r -> r.key(recordKey)).join();
625-
assertThat(deletedItem).isNull();
626-
}
627-
628-
@Test
629-
public void deleteRecordWithVersion_andOptimisticDeleteDisabled_ifVersionMismatch_shouldSucceed() {
630-
initEnhancedClient(false);
631-
VersionedRecord originalItem = new VersionedRecord().setId("123").setSort(10).setStringAttribute("Original Item");
632-
Key recordKey = Key.builder().partitionValue(originalItem.getId()).sortValue(originalItem.getSort()).build();
633-
634-
// Put the item
635-
versionedRecordTable.putItem(originalItem).join();
636-
637-
// Retrieve the item, modify it separately and update it, which will increment the version
638-
VersionedRecord savedItem = versionedRecordTable.getItem(r -> r.key(recordKey)).join();
639-
savedItem.setStringAttribute("Updated Item");
640-
versionedRecordTable.updateItem(savedItem).join();
641-
642-
// Get the updated item and try to delete it
643-
VersionedRecord updatedItem = versionedRecordTable.getItem(r -> r.key(recordKey)).join();
644-
versionedRecordTable.deleteItem(updatedItem).join();
645-
646-
Record deletedItem = mappedTable.getItem(r -> r.key(recordKey)).join();
647-
assertThat(deletedItem).isNull();
648-
}
649-
650-
/**
651-
* Re‐initializes the {@link DynamoDbEnhancedClient} to use a fresh {@link VersionedRecordExtension} with the given optimistic
652-
* delete flag, then rebinds both the un-versioned and versioned table references.
653-
*
654-
* @param optimisticDelete if {@code true}, table.deleteItem()/enhancedClient.transactWriteItems() operations will include a
655-
* version‐match condition; if {@code false}, the deletion proceeds unconditionally.
656-
*/
657-
private static void initEnhancedClient(boolean optimisticDelete) {
658-
enhancedClient = DynamoDbEnhancedAsyncClient.builder()
659-
.dynamoDbClient(dynamoDbClient)
660-
.extensions(VersionedRecordExtension.builder()
661-
.optimisticLockingOnDelete(optimisticDelete)
662-
.build())
663-
.build();
664-
665-
mappedTable = enhancedClient.table(TABLE_NAME, TABLE_SCHEMA);
666-
versionedRecordTable = enhancedClient.table(TABLE_NAME, VERSIONED_RECORD_TABLE_SCHEMA);
667-
}
668502
}

0 commit comments

Comments
 (0)