Amazon DynamoDb:如何实现putIfAbsent?

时间:2017-08-01 15:54:39

标签: java amazon-dynamodb

我需要为DynamoDb实施Map.putIfAbsent(K key, V value)

/**
 * If the specified key is not already associated with a value (or is mapped
 * to {@code null}) associates it with the given value and returns
 * {@code null}, else returns the current value.
 *
 * @implSpec
 * The default implementation is equivalent to, for this {@code
 * map}:
 *
 * <pre> {@code
 * V v = map.get(key);
 * if (v == null)
 *     v = map.put(key, value);
 *
 * return v;
 * }</pre>

到目前为止,我有这个问题:

    Item oldItem = this.table.updateItem(
            new UpdateItemSpec()
                    .withPrimaryKey(KEY, key)
                    .withAttributeUpdate(
                            new AttributeUpdate(VALUE)
                                    .put(value))
                    .withExpected(
                            new Expected(KEY)
                                    .notExist())
                    .withReturnValues(ReturnValue.ALL_OLD))
            .getItem();

但是在存在的情况下,我得到ConditionalCheckFailedException

当任何条件评估为false时,看起来总是抛出此异常。

我知道我可以捕获该异常并执行额外的getItem(),但我真的要在一个原子请求中执行所有操作。

1 个答案:

答案 0 :(得分:1)

我认为如果不使用多个API调用,您可能无法使用DynamoDB低级API实现上述功能。

如果您使用DynamoDB高级API,即DynamoDBMapper,则此类上的save()方法具有此功能。

DynamoDBMapper

保存行为: -

  

UPDATE(默认值):UPDATE不会影响a上的未建模属性   保存操作,建模属性的空值将被删除   它来自DynamoDB中的那个项目。由于updateItem的限制   请求,UPDATE的执行时会发送一个putItem请求   正在保存一个仅限密钥的对象,它将发送另一个updateItem   请求表中是否已存在给定的密钥。

     

UPDATE_SKIP_NULL_ATTRIBUTES:与UPDATE类似,但忽略它   任何空值属性,并不会从中删除它们   DynamoDB。它还保证只发送一个updateItem   请求,无论对象是否为key-only。

     

CLOBBER:CLOBBER   将清除并替换所有属性,包括未建模的属性,   (保存时删除并重新创建)。版本化的字段约束也将   被忽视。 saveExpression参数中指定的任何选项   将由于版本化属性而叠加在任何约束上。