4

我正在编写一个“获取或创建”方法来尝试获取一个项目,但如果它不存在,它将创建一个全新的版本。显然,我想确定该项目在我尝试获取它时不存在,因此它永远不会覆盖现有数据。

我是否正确假设$result["Item"] === null 当且仅当该项目在请求时数据库中不存在?也就是说,如果项目在请求之前存在,那么无论 API 错误等如何,此条件是否总是评估为假?或者还有其他我应该检查的东西吗?

    $result = $this->client->getItem(
        array(
            "TableName" => $tableName,
            "Key" => array(
                $keyName => array(Type::STRING => $key),
            )
        )
    );

    if ( $result["Item"] === null )
    {
        //Item does not exist; create it and write it to dynamoDb (code not shown)
    }

    return $result["Item"];
4

2 回答 2

3

我要补充'ConsistentRead' => true一点,以确保您的阅读获得绝对的、最新的数据。

您仍然会在这里遇到潜在的竞争条件,如果多个进程尝试获取该项目并发现它不存在,那么它们都会尝试写入该项目,但只有一个进程不会破坏其数据。只要没有机会他们会写入不同的数据,那就无所谓了。

于 2013-08-20T01:31:56.490 回答
0

考虑一个有条件的 put,您在执行 put 之前指定 key 不能存在。这避免了任何竞争条件,并且只需要一次调用。唯一的缺点是您必须通过网络发送整个新项目,即使它已经存在。

向下滚动到此处的“指定可选参数”部分:http: //docs.aws.amazon.com/amazondynamodb/latest/developerguide/LowLevelJavaItemCRUD.html#PutLowLevelAPIJava

代码应如下所示:

// Optional parameters Expected and ReturnValue.
Map<String, ExpectedAttributeValue> expected = new HashMap<>();
expected.put(
    "hashKeyAttributeName",
    new ExpectedAttributeValue()
        .withValue(new AttributeValue().withS("hashKeyValue"))
        .withExists(false)
);
于 2013-08-20T08:11:45.360 回答