如何使用 Spring Boot 在 DynamoDB 中添加具有自动增量键的新项目

Posted

技术标签:

【中文标题】如何使用 Spring Boot 在 DynamoDB 中添加具有自动增量键的新项目【英文标题】:How can I add new item with auto-increment key in DynamoDB with Spring Boot 【发布时间】:2021-12-30 10:33:16 【问题描述】:

我想将DynamoDB 中的主键设为自动增量键,例如SQL。 并且生成这个之后,如果顺序有缺失的项目,(删除一些项目后)

+--------+---------------+
|   id   |      name     |
+--------+---------------+
|    1   |  AuctionStart |    
+--------+---------------+
|    2   |   AuctionEnd  |
+--------+---------------+
|    5   |      Bid      |
+--------+---------------+
|    7   |     OutBid    |
+--------+---------------+

在这种情况下,我想插入具有 3、4、6 的项目,然后是 8、9、10 ... 我如何使用Spring Boot + DynamoDB 做到这一点?

【问题讨论】:

我不确定你是否可以。一般来说,自动递增,你会得到最后一个 ID,在这种情况下是 7,然后递增,它变成 8。它不寻找“丢失”的内容。通常在自动递增 ID 时,规则是它们存在唯一性,删除后丢失 1 或 2 个应该被认为是可以的。让我们看看其他人是否会知道这是否可行.. 感谢您的关注。希望有解决这个问题的办法 会有多个插入并行发生的情况吗?如果 INSERT、DELETE 一起出现会发生什么?即如果插入 1,2,3 并且先处理 INSERT,则 INSERT 记录获取 id 4。如果先发生 DELETE:2 然后 INSERT 发生,则 INSERT 获取 id:2,我希望这没问题? 【参考方案1】:

DynamoDB 没有自动增量,但以下两个功能应该可以帮助您使用以下 DynamoDB 功能实现您想要的功能:

DynamoDB 支持transactions,其中多个表可以同时原子更新 DynamoDB 还支持conditional expressions,这将确保我们可以根据条件停止更新

下面是一个使用上述功能的简单想法


我们称您的表为 DATA 您可以维护另一个 COUNTER 表,该表存储丢失的键和到目前为止分配的最高 ID(如下所示,其值为 Document 类型)

   Key        Value                                                RecordVersionNumber
+-------------+-----------------------------------------------------+--------+
| Counter     |   "Highestid": 7, "MissingKeys": ["3,4,6"]        |  10    |
+-------------+-----------------------------------------------------+--------+

如果从数据表中删除,DELETE 会将 ID 添加到 missingKeys INSERT 可以选择丢失的键之一,在这种情况下,它会从丢失的键中删除元素 如果 missingKeys 为空,则 INSERT 将改为编辑 HighestId

检查 DynamoDB 列大小限制并为您的数据设计相应的表 计数器不必是专门的表,您甚至可以使用 DATA 表的某一行。我使用了单独的表格进行说明 看看transaction isolation levels

为了使您的自动增量版本能够在每个操作期间自动执行以下步骤:

DELETE期间:

    写入 DATA 表:使用conditional delete 删除具有给定 id 的记录(如果存在) 从 COUNTER 表中读取:读取现有的缺失键 写入 COUNTER 表:将删除的 Id 添加到 missingKeys,对列表进行排序,将 RecordVersionNumber 增加 1 并对 RecordVersionNumber 执行条件更新

读取 (2) 在 Java 代码中完成,写入准备为 TransactWriteItem 语句 如果 (1) 由于密钥不存在而失败,则其他步骤将不会发生 在 (3) 中,为了避免并行调用破坏我们的数据,我们必须添加条件检查以确保 仅当现有记录的 RecordVersionNumber 与我们在 (2) 中读取的记录相同时才写入

即(3) 如果任何其他 INSERT/DELETE 操作在我们在 (2) 中读取计数器后编辑了计数器,则会失败并出现 ConditionalCheckFailed 异常

需要处理 ConditionalCheckFailed 操作,整个方法:(1)、(2)、(3) 应该在返回失败响应之前重试几次


插入期间:

    从 COUNTER 表中读取:读取现有的缺失键,HighestId 写入 DATA 表:为新的“Id-Name”记录执行Conditional put。如果 missingKeys 为空,则 id=HighestId+1 else Id=missingKeys.first 写入 COUNTER 表:根据步骤 (2) 中的操作,删除分配的 missingKeys 值或增加最高 ID,写回记录并在 RecordVersionNumber 上进行条件更新

如果两个 INSERT 调用并行发生,则两者都可以读取相同的 COUNTER 数据并尝试将冲突的 id 写入 DATA 表。 在这种情况下,由于 ConditionalCheckFailed 错误,其中一个插入将在 (2) 处失败,应重试步骤 (1 到 3)

如果在我们读取 (1) 中缺失的键后,由于 DELETE 导致 COUNTER 表被修改,则步骤 (3) 将失败,整个 (1-3) 应在代码中重试


如果您能够对 INSERT/DELETE 操作的数量进行排队或控制并行执行的数量,则应减少由于并行调用而导致的重试次数

【讨论】:

以上是关于如何使用 Spring Boot 在 DynamoDB 中添加具有自动增量键的新项目的主要内容,如果未能解决你的问题,请参考以下文章

如何在 spring-boot 中禁用 spring-data-mongodb 自动配置

如何在 Spring Boot 中使用 @Transactional 注解

Dynamo For Revit: 如何通过选中一些模型线,来创建一堵墙

如何在没有spring-boot的情况下使用eureka+feign?

使用nodejs的AWS Dynamo DB生产设置

如何使用 Spring-Boot 播种 Spring-Security