我正在编写一个尝试获取项目的“获取或创建”方法,但如果它不存在,它将创建一个全新的版本。显然,我想知道当我试图获取它时该项目不存在,因此它永远不会覆盖现有数据。
我是否正确假设$result["Item"] === null
当且仅当在请求时数据库中不存在该项目时?也就是说,如果项目在请求之前存在,那么无论API错误如何,此条件是否总是评估为false?或者还有其他我应该检查的东西吗?
$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"];
答案 0 :(得分:3)
我会添加'ConsistentRead' => true
以确保您的阅读获得绝对的,最新的数据。
你仍然会有一个潜在的竞争条件,如果多个进程试图获取该项并看到它不在那里,那么他们都将尝试编写该项,但只有一个进程赢了#t有其数据被破坏。只要他们没有机会写出不同的数据,那就无所谓了。
答案 1 :(得分:0)
考虑一个条件put,你指定在执行put之前键不能存在。这可以避免任何竞争条件,并且只需一次通话。唯一的缺点是你必须通过电线发送整个新项目,即使它已经存在。
在此处向下滚动到“指定可选参数”部分: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)
);