java - DynamoDb.创建时有条件写入。通过字段检查是否不等于(NE)

标签 java amazon-web-services transactions amazon-dynamodb

假设,我想将新项目保存/创建到 DynamoDb 表中, 当且仅当不存在任何现有项目包含与我设置的值相同的 referenceId 时。

就我而言,如果表中没有任何其他 withReferenceId=123,我想使用 withReferenceId=123 创建一个项目。

referenceId 不是主键! (我不想这样)

所以代码:

 val withReferenceIdValue = "123";
 val saveExpression = new DynamoDBSaveExpression();

    final Map<String, ExpectedAttributeValue> expectedNoReferenceIdFound = new HashMap();
    expectedNoReferenceIdFound.put(
            "referenceId",
            new ExpectedAttributeValue(new AttributeValue().withS(withReferenceIdValue)).withComparisonOperator(ComparisonOperator.NE)
    );
    saveExpression.setExpected(expectedNoReferenceIdFound);

    newItemRecord.setReferenceId(withReferenceId);

    this.mapper.save(newItemRecord, saveExpression); // do not fail..

这似乎不起作用。

表中已有 referenceId=123save() 不会失败。 我预计 this.mapper.save 会失败并出现异常。

问:如何使其有条件失败?

我还检查了 this one 他们建议添加辅助表(事务状态表)..因为似乎 saveExpression 仅适用于主/分区键...如果是这样:

not sure why there that limitation. in any case if it is primary key one can not create duplicated item with the same primary key.. why creating conditions on first place. 3rd table is too much.. why there is not just NE to whatever field I want to use. I may create an index for this filed. not being limited to use only primary key.. that what I mean

更新:

我的表映射代码:

@Data // I use [lombok][2] and it does generate getters and setters.
@DynamoDBTable(tableName = "MyTable")
public class MyTable {

    @DynamoDBHashKey(attributeName = "myTableID")
    @DynamoDBAutoGeneratedKey
    private String myTableID;
    @DynamoDBAttribute(attributeName = "referenceId")
    private String referenceId;
    @DynamoDBAttribute(attributeName = "startTime")
    private String startTime;
    @DynamoDBAttribute(attributeName = "endTime")
    private String endTime;
    ...
}

最佳答案

如果我错了,请纠正我,但来自:

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/dynamodb-dg.pdf

Conditional Writes By default, the DynamoDB write operations (PutItem, UpdateItem, DeleteItem) are unconditional: each of these operations will overwrite an existing item that has the specified primary key

主键 - 这让我认为条件写入仅适用于主键

--

还尝试使用事务方式从数据库读/写。有一个图书馆。该事件没有 Maven 仓库:https://github.com/awslabs/dynamodb-transactions

作为替代方案,似乎是使用带有主键的第三个事务表,该主键负责告诉您是否可以读取或写入该表。 (丑陋)正如我们在这里回复的:DynamoDBMapper save item only if unique

我猜(根据设计)还有另一种选择:以某种方式设计表,以便使用主键作为业务键,这样您就可以将其用于条件写入 .

--

另一个选择:使用 Aurora :)

--

另一个选项(正在调查):https://aws.amazon.com/blogs/database/building-distributed-locks-with-the-dynamodb-lock-client/ ——这个我也不喜欢。因为它可能会为其他想要在此表中创建新项目的人造成超时。

--

另一个选项:接受这个,让项目创建时发生重复(不包括主键)。并将其作为“垃圾收集”的一部分来处理。取决于场景。

关于java - DynamoDb.创建时有条件写入。通过字段检查是否不等于(NE),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50005071/

相关文章:

java - Tomcat 等待加入 jgroups 集群

Java 找不到 java.util.function.Consumer

amazon-web-services - 使用 AWS Application Load Balancer 的 Websocket 超时

mongodb - 从 shell 脚本连接中运行 MongoDB shell 命令被拒绝

java - 如何在 Java 或 clojure 中使用 ImageJ 进行批量图像处理?

java - 确保不调用特定方法的自定义 lint 规则

amazon-web-services - Kubernetes:如何正确更改apiserver运行时设置

ruby-on-rails - 事务与截断数据库清理器

c# - 我是否应该始终在 nhibernate 中使用事务(即使是简单的读写)?

java - 通过 Spring + Hibernate 只读数据