如何使用 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: 如何通过选中一些模型线,来创建一堵墙