2013-08-19 91 views
3

我正在編寫一個試圖獲取項目的「獲取或創建」方法,但如果它不存在,它將創建一個全新的新版本它。很顯然,我想知道確實該項目在我試圖獲取時不存在,因此它不會覆蓋現有數據。DynamoDB PHP getItem() - 如何判斷項是否不存在

我是否正確假設$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"]; 

回答

3

我會爲了增加'ConsistentRead' => true確保你讀的是獲得絕對的,最先進的最新數據。

你仍然會在這裏有一個潛在的競爭條件,如果多個進程試圖獲得該項目,並看到它不在那裏,那麼他們都會嘗試寫入該項目,但只有一個進程不會有其數據遭到破壞。只要他們沒有機會寫出不同的數據,那麼這並不重要。

0

考慮一個有條件的放置,你可以在放置之前指定鍵不能存在。這樣可以避免任何競爭狀況,並且只需要一個電話。唯一的缺點是你必須通過電線發送整個新物品,即使它已經存在。

向下滾動到「指定可選參數」一節在這裏: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) 
); 
+0

是的,這會工作,但我真的不喜歡時的開銷廣闊大部分請求(超過99%)不會創建數據。 – Fragsworth

+0

@Fragsworth嗯......你也可以同時使用兩種技術(get和check,然後是有條件的put),這樣你可以節省開銷,但是在競賽條件下理論上是安全的。 –

相關問題