首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >正确使用DynamoDB乐观锁的方法

正确使用DynamoDB乐观锁的方法
EN

Stack Overflow用户
提问于 2016-02-27 17:06:41
回答 3查看 25K关注 0票数 9

我正在努力理解,DynamoDB乐观锁定对于我的用例来说是正确的,还是应该做其他的事情。

我正试图在我的Java方法中执行以下操作。

代码语言:javascript
运行
复制
function updateItem(String key) {
    Item item = mapper.load(Item.class, key);
    if (some condition) {
        item.setValue(item.getValue() + 1);
        mapper.save(item);
    }
 }

我想根据成功的条件更新相同的项目。我已经创建了一个version属性,这样乐观锁定就可以工作了,当我有多个请求进来时,只有一个请求会获取和更新数据。

我试图理解以下几点:

  1. 当其他线程试图更新该值但版本id已更改时,我无法找到将抛出哪个异常的任何文档,会发生什么?
  2. 我应该为此使用同步函数吗?考虑到会有多个请求出现?但是,在我看来,这似乎违背了乐观锁定的目的,因为我不关心哪个请求首先获得访问权。
  3. 这个问题有其他的解决办法吗?

我已经看过以下文档:http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptimisticLocking.html

EN

回答 3

Stack Overflow用户

发布于 2017-07-08 09:36:38

如果需要确保应用了所有多个请求(来自不同线程/服务器),则可以使用以下乐观锁定实现:

代码语言:javascript
运行
复制
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 -当期望值与系统(数据库)中的内容不匹配时,会引发此异常。将引发此异常:

  • 如果对@DynamoDBVersionAttribute使用乐观锁定,服务器上的版本值与客户端的值不同;
  • 如果在使用dynamoDBMapper与DynamoDBSaveExpression / DynamoDBDeleteExpression一起保存/删除数据时指定自己的条件约束,则这些约束将失败。

关于@Nawaz问题,如果您没有指定自己的条件约束(使用DynamoDBSaveExpression和DynamoDBDeleteExpression),则此异常是由于版本更改造成的。如果捕捉到ConditionalCheckFailedException,您将获得以下信息:

代码语言:javascript
运行
复制
requestId = …
errorCode = ConditionalCheckFailedException
errorType = {AmazonServiceException$ErrorType} "Client"
errorMessage = The conditional request failed
statusCode = 400
serviceName = AmazonDynamoDBv2
票数 8
EN

Stack Overflow用户

发布于 2016-02-27 17:58:31

  1. 当其他线程试图更新该值但版本id已更改时,我无法找到将抛出哪个异常的任何文档,会发生什么?

如果版本ID已经更改,它似乎会抛出一个ConditionalCheckFailedException。

  1. 我应该为此使用同步函数吗?考虑到会有多个请求出现?但是,在我看来,这似乎违背了乐观锁定的目的,因为我不关心哪个请求首先获得访问权。

您是正确的,使用同步函数将无法达到乐观锁定的目的。你不需要两者兼得。乐观锁定在分布式环境中工作,在这种环境中,更新可能不会由相同的服务器生成。

  1. 这个问题有其他的解决办法吗?

您可以使用低级别的DynamoDB API和条件更新。我认为这就是乐观锁定的使用方式。如果使用的是Java或.Net以外的语言,则必须使用低级别的API。由于您使用的是Java,并且已经使用了高级API,所以我会坚持这样做。

票数 7
EN

Stack Overflow用户

发布于 2020-07-16 10:28:26

现在正式支持乐观锁定:

AWS文件

您需要在字段中添加@DynamoDBVersionAttribute。如果您需要更复杂的数据锁,请考虑条件约束,它们允许锁定数据并防止不必要的修改。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35672713

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档