我正在努力理解,DynamoDB乐观锁定对于我的用例来说是正确的,还是应该做其他的事情。
我正试图在我的Java方法中执行以下操作。
function updateItem(String key) {
Item item = mapper.load(Item.class, key);
if (some condition) {
item.setValue(item.getValue() + 1);
mapper.save(item);
}
}
我想根据成功的条件更新相同的项目。我已经创建了一个version属性,这样乐观锁定就可以工作了,当我有多个请求进来时,只有一个请求会获取和更新数据。
我试图理解以下几点:
发布于 2017-07-08 09:36:38
如果需要确保应用了所有多个请求(来自不同线程/服务器),则可以使用以下乐观锁定实现:
public void updateItem(String key) {
while (true) {
try {
Item item = dynamoDBMapper.load(Item.class, key);
if (some condition) {
item.setValue(item.getValue() + 1);
dynamoDBMapper.save(item);
}
break;
} catch (ConditionalCheckFailedException e) {
System.out.println("ConditionalCheckFailedException. Retrying again...");
}
}
}
在这里,如果项目已经被另一个请求更新,我们将收到ConditionalCheckFailedException并再次尝试,直到应用更改为止。
ConditionalCheckFailedException -当期望值与系统(数据库)中的内容不匹配时,会引发此异常。将引发此异常:
关于@Nawaz问题,如果您没有指定自己的条件约束(使用DynamoDBSaveExpression和DynamoDBDeleteExpression),则此异常是由于版本更改造成的。如果捕捉到ConditionalCheckFailedException,您将获得以下信息:
requestId = …
errorCode = ConditionalCheckFailedException
errorType = {AmazonServiceException$ErrorType} "Client"
errorMessage = The conditional request failed
statusCode = 400
serviceName = AmazonDynamoDBv2
发布于 2016-02-27 17:58:31
如果版本ID已经更改,它似乎会抛出一个ConditionalCheckFailedException。
您是正确的,使用同步函数将无法达到乐观锁定的目的。你不需要两者兼得。乐观锁定在分布式环境中工作,在这种环境中,更新可能不会由相同的服务器生成。
您可以使用低级别的DynamoDB API和条件更新。我认为这就是乐观锁定的使用方式。如果使用的是Java或.Net以外的语言,则必须使用低级别的API。由于您使用的是Java,并且已经使用了高级API,所以我会坚持这样做。
https://stackoverflow.com/questions/35672713
复制相似问题