我是DynamoDB的新手,正在尝试使用事务支持的示例方案。我正在使用dynamodb事务库中提供的相同实体。唯一的不同是,我使用哈希键添加了范围键。这是表的定义:

  • ItemId->哈希键,字符串
  • ItemName->范围键,字符串

  • @DynamoDBTable(tableName = "Item")
    public static class ExampleItem {
        private String itemId;
        private String value;
        private String itemName;
        private Long version;
        @DynamoDBHashKey(attributeName = "ItemId")
        public String getItemId() {
            return itemId;
        }
        public void setItemId(String itemId) {
            this.itemId = itemId;
        }
        @DynamoDBRangeKey(attributeName="ItemName")
        public String getItemName() {
            return itemName;
        }
        public void setItemName(String itemName) {
            this.itemName = itemName;
        }
        public String getValue() {
            return value;
        }
        public void setValue(String value) {
            this.value = value;
        }
        @DynamoDBVersionAttribute
        public Long getVersion() {
            return version;
        }
        public void setVersion(Long version) {
            this.version = version;
        }
    }
    

    如您所见,我也在使用version属性。
    现在,我正在尝试使用transaction/dbmapper执行一个简单的创建或更新方案。这是代码片段。
    Transaction t1 = txManager.newTransaction();
    ExampleItem keyItem = new ExampleItem();
    keyItem.setItemId("Item1");
    keyItem.setItemName("USA");
    ExampleItem item = t1.load(keyItem);
    if (item != null) {
        item.setValue("Magenta");
        item.setItemName("UK");
        t1.save(item);
    } else {
        item = new ExampleItem();
        item.setItemId(keyItem.getItemId());
        item.setItemName("USA");
        item.setValue("Violet");
        t1.save(item);
    }
    t1.commit();
    t1.delete();
    

    我可以毫无问题地添加记录,但是在尝试读取记录并更新任何属性时遇到了问题。我收到以下异常:
    Uncaught exception:com.amazonaws.services.dynamodbv2.model.ConditionalCheckFailedException: Status Code: 0, AWS Service: null, AWS Request ID: null, AWS Error Code: null, AWS Error Message: Item {ItemId={S: Item1,}, ItemName={S: UK,}} had unexpected attributes: Status Code: 0, AWS Service: null, AWS Request ID: null, AWS Error Code: null, AWS Error Message: expected attribute(s) {version={Value: {N: 1,},Exists: true}} but found null
    com.amazonaws.services.dynamodbv2.model.ConditionalCheckFailedException: Status Code: 0, AWS Service: null, AWS Request ID: null, AWS Error Code: null, AWS Error Message: Item {ItemId={S: Item1,}, ItemName={S: UK,}} had unexpected attributes: Status Code: 0, AWS Service: null, AWS Request ID: null, AWS Error Code: null, AWS Error Message: expected attribute(s) {version={Value: {N: 1,},Exists: true}} but found null
    

    看起来它与版本有关,但不确定我在哪里出错。任何指针将不胜感激。

    -谢谢

    沙米克

    最佳答案

    Dynamodb具有Optimistic Locking的概念,该策略可确保您要更新(或删除)的客户端项目与DynamoDB中的项目相同。

  • 首先保存:

  • 如果是第一次更新,则必须遵循此格式
    DynamodbSaveExpression saveExpression =
           new DynamodbSaveExpression()
           .withExpectedEntry("ItemId", new ExpectedAttributeValue().withExists(false)
           .withConditionalOperator(AND)
           .withExpectedEntry("ItemName", new ExpectedAttributeValue().withExists(false));
    // saving the item to dynamodb
    dynamodbmapper.save(itemToSave, saveExpression);
    

    说明:我们告诉我们,只有在dynamodb中同时没有“ItemId”,“ItemValue”组合时,才应保存itemToSave。
  • 更新到现有项目:

  • 要更新dynamodb中的现有项目,您必须遵循以下格式
    // Step1: Do a GET
    ExampleItem itemInDynamo = dynamoDBMapper.load(ExampleItem.class, "item_id_value", "item_name_value");
    // Step2: Get the version in Dynamo
    Long versionInDynamo = itemInDynamo.getVersion();
    DynamodbSaveExpression saveExpression =
           new DynamodbSaveExpression()
           .withExpectedEntry("version",
           new ExpectedAttributeValue(new AttributeValue().withN(versionInDynamodb.toString())));
    // Step3: Update the item
    dynamodbmapper.save(itemToSave, saveExpression);
    

    仅当要保存的版本与Dynamodb中的版本相同时,保存才会成功;如果不保存,则返回的ConditionalCheckFailedException将会失败,则您已从步骤1开始重试。这是先读然后写。

    关于java - Dynamodb ConditionalCheckFailedException上的读取/更新操作-Java SDK,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26533223/

    10-16 04:08