【问题标题】:Using DynamoDBSaveExpression to Check Existence of Other Key使用 DynamoDBSaveExpression 检查其他键是否存在
【发布时间】:2018-11-24 05:22:19
【问题描述】:

作为一个简单的例子,我有一个如下所示的类:

public class DbData {
    @DynamoDBAutoGeneratedKey
    @DynamoDBHashKey(attributeName = "id")
    private UUID id;
    private UUID parent;
    // other fields ...
}

此类存储在 DynamoDB 表中。当向表中添加新条目时,我想确保父项已经存在(如果设置了父项)。

这可以使用 DynamoDBSaveExpression 完成吗?

比如我可以确定当前id不存在:

new DynamoDBSaveExpression()
    .withExpectedEntry("id", new ExpectedAttributeValue().withExists(false));

我认为这可能有效,但它没有:

    ExpectedAttributeValue expectedAttributeValue = new ExpectedAttributeValue(new AttributeValue(parent.toString()));
    dynamoDBSaveExpression = new DynamoDBSaveExpression()
            .withExpectedEntry("id", new ExpectedAttributeValue().withExists(false));
            .withExpectedEntry("id", expectedAttributeValue.withExists(true))
            .withConditionalOperator(ConditionalOperator.AND);

编辑

有一个 RESTful API 定义了一个 POST 来创建资源,并且该资源作为一个条目存储在 DynamoDB 表中。

资源允许使用父标识符指定的层次结构。

如果找不到父资源,则返回 404:

a. if parent identifier is set
b.     get parent resource from DynamoDB
c.     if parent not found
d.         return 404
e. persist resource in DynamoDB

伪代码不是原子的。 'b' 可能会返回父级,但另一个线程/进程可能会在 'e' 之前将其删除。

我希望条件表达式在这里会有所帮助。 transaction library 是实现此目的的唯一方法吗?或者,是否应该对数据进行不同的建模?

【问题讨论】:

  • 如果您可以提供有关您的用例的更多信息,那么有人可能会提供替代解决方案。
  • 我用一个用例更新了这个问题,谢谢你的建议。
  • DynamoDB Transactions 刚刚在 re:Invent 大会上宣布。它们可能是您的解决方案。我还不熟悉它们的具体工作原理,但我建议您查看docs.aws.amazon.com/amazondynamodb/latest/developerguide/… 的文档

标签: java amazon-dynamodb aws-java-sdk


【解决方案1】:

以下答案基本上已过时,但我将其留给后代。 DynamoDB now supports transactions 允许您为同一个或另一个表中的不同键值提供条件表达式。


不,ConditionExpression 不能查看当前正在保存/更新/删除的项目以外的任何项目。

更新

如果可能,您能否将您的数据设计为无法删除的内容? (也许您可以将其标记为过时。)这完全消除了问题,因为一旦存在,它将永远存在。

如果这不可能,您可能需要查看DynamoDBLockClient。它提供了一个由 DynamoDB 支持的通用分布式锁定 API。

你的新伪代码是

a. if parent identifier is set
b.     Acquire lock for parent identifier
c.     get parent resource from DynamoDB
d.     if parent not found
e.         Release lock
f.         return 404
g. persist resource in DynamoDB
h. Release lock

此外,在删除作为父标识符的内容的任何操作中,您应该在删除它之前获取对该父标识符的锁定。如果您这样做,您可以确保在创建子节点的过程中不会删除父节点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-27
    • 2021-12-10
    • 1970-01-01
    • 2012-01-07
    • 2023-03-30
    • 2015-12-04
    • 2012-09-08
    • 1970-01-01
    相关资源
    最近更新 更多