DynamoDB自动更新计数器

时间:2018-09-19 07:02:38

标签: concurrency amazon-dynamodb atomicity dynamodb-queries

DynamoDB新手,对学习NoSQL数据库感兴趣。

在一种情况下,我有一个表,该表具有userId的分区键,时间的排序键和数字句柄。该句柄是一个递增1的顺序计数器。

以下是表格的示例:

userId, time, handle
0     , 123 , 1
0     , 456 , 2
1     , 123 , 1
1     , 234 , 2
0     , 789 , 3
1     , 345 , 3

对于给定的userId,句柄不能重复

我想要做的是为时间891添加一个userId 0的新记录,并具有一个比userId 0的最后写入记录大的句柄1-这将是数据库中的倒数第二行,即,3 +1 =4。

幼稚的方法是查询数据库的userId为0,并按最后一个时间戳(如果可能的话)排序以获得句柄(3)。那是第一个请求。然后,您将在数据库上创建一个put_item请求,该请求会将句柄加1(3 + 1 = 4)并创建新记录。

这里显然有一个竞争条件,在读取查询和创建put_item请求之间,另一个lambda / API /端点可能已经向具有相同句柄(4)的数据库提交了一条新记录,例如(1、888、4)。当我提交原始记录(0、891、4)时,句柄是4,现在应该是5。

是否可以在单个事务中执行此读取和写入操作(也许我心态错误)。

让我知道我的问题是否很清楚。

2 个答案:

答案 0 :(得分:1)

您可能需要第二张表来容纳一个原子计数器,该计数器持有每个userId的最高句柄。当您需要添加记录时,可以在第二个表中以原子方式递增userId的计数器,然后从计数器中获取值并将其用于新记录。

答案 1 :(得分:1)

您要尝试做的事情:“将单调递增的数值分配为唯一标识符”是分布式数据库(noSql或其他方式)的反模式。

花点时间考虑问题。

如果您可以将GUID用作唯一标识符,则不再需要查询以确定最后使用的标识符,并且始终保证有唯一值。

如果您需要ID具有一些顺序概念,则应考虑采用一种策略,从时间戳和一些较小的随机值中生成ID。如果您尝试插入具有重复标识符的记录,则只需重试。

否则,使用任意单调递增整数的方法是将它们存储在用户级别(同一表或单独的表),但是每次更新用户记录时,您都将更新相同的键,从而降低了可伸缩性。

最后-如果对于每个用户来说,只有很少的记录要存储,请考虑将这些记录合并为一个项目的方案。