读取/更新操作时发生Dynamodb ConditionalCheckFailedException
我是DynamoDB的新手,并尝试使用Transaction支持的示例场景。 我正在使用dynamodb-transaction库中提供的相同实体。 唯一的区别是我用散列键添加了一个范围键。 这里是表格定义:
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;
}
}
正如你所看到的,我也使用了版本属性。 现在,我正尝试使用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
看起来它与版本有关,但不知道我错在哪里。 任何指针将不胜感激。
-谢谢
Shamik
看起来您需要在创建项目类时设置版本。 它期待1,但发现空。 versionedAttribute期待一个值,并且它看起来是该项目第一次创建时期望值为1。
如果将来更新此项目,它应该负责在内部增加版本。
Dynamodb具有乐观锁定的这一概念,是确保您正在更新(或删除)的客户端项目与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步开始重试。 这是先读然后写。
Usualy这种情况发生在您的密钥与dynamodb中的多个元素相同时。 例如,如果您将文件夹的id设置为hashKey,将folderName设置为rangeKey,则您不会再次将文件夹另存为您的散列 (hashkey + rangeKey)所在的位置。
链接地址: http://www.djcxy.com/p/82221.html上一篇: Dynamodb ConditionalCheckFailedException on read / update operation