【问题标题】:DynamoDB PHP getItem() - How to tell if item does not existDynamoDB PHP getItem() - 如何判断项目是否不存在
【发布时间】:2013-08-21 09:28:03
【问题描述】:

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

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

【问题讨论】:

    标签: php amazon-dynamodb


    【解决方案1】:

    我会添加'ConsistentRead' => true 以确保您的阅读获得绝对、最新的数据。

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

    【讨论】:

      【解决方案2】:

      考虑一个有条件的 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)
      );
      

      【讨论】:

      • 是的,这可行,但我真的不喜欢绝大多数请求(超过 99%)不会创建数据时的开销。
      • @Fragsworth 嗯...您还可以使用这两种技术(get 和 check,然后是条件 put),这样可以节省开销,但理论上可以避免竞争条件。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-12
      • 1970-01-01
      • 2016-12-06
      • 2021-07-26
      • 2013-10-31
      相关资源
      最近更新 更多