是否有可能,并且是否将DynamoDb乐观锁定版本暴露给客户端,以防止更高级别的竞争情况?

问题描述 投票:0回答:1

这是一般比赛条件问题

  1. 使用列表创建资源
  2. ServiceA和ServiceB希望在Resource列表中添加一些内容
    1. ServiceA获取资源(list = [])
    2. ServiceB获取资源(list = [])
    3. ServiceA更新资源(列表= [A])并成功
    4. ServiceB更新资源(列表= [B])并成功

预期:资源(list = [A,B])或异常

实际:资源(列表= [B])更糟糕的是,这是一个无声的失败

使用DynamoDB's Optimistic Locking with Version Number,我们可以解决这个问题,并且情况看起来像这样。

  1. 使用列表(和版本= 1)创建资源
  2. ServiceA和ServiceB希望在Resource列表中添加一些内容
    1. ServiceA获取资源(列表= [],版本= 1)
    2. ServiceB获取资源(列表= [],版本= 1)
    3. ServiceA更新资源(列表= [A],版本= 1)并成功(版本变为2)
    4. ServiceB更新资源(列表= [B],版本= 1),并且由于版本落后而失败

因此,ServiceB收到了故障通知,可以通过重新获取资源(版本= 2和列表= [A])并更新资源(列表= [A,B],版本= 2)来决定重试该尝试。

DynamoDB为您管理版本。创建资源时,它将版本设置为1,在每次更新时自动将其递增,如果版本不匹配,则引发异常。

我的问题是,是否可以在客户端的Get-Requests中公开该版本(假设客户端不是我们的代码,而是我们组织拥有的其他服务),并允许他们在Update-中提供它,请求?

  • 该问题的第一部分是,这在技术上可行吗?
  • 该问题的第二部分是,这是好的做法吗? (即,即使从技术上讲,这样做是否存在任何问题?)
transactions amazon-dynamodb optimistic-locking
1个回答
0
投票

首先,DynamoDB实际上没有记录版本控制的概念。一些库引入了该概念,这些库添加了版本字段并在Condition Expressions调用中利用了PutItem。因此,就此而言,您实际上并没有公开DynamoDB值,而是公开了选择添加到数据中的值(尽管通过SDK)。

第二,很可能有更好的方法。考虑使用UpdateItem,并利用一些更高级的UpdateExpressions,特别是ADD操作。

如果现有数据类型是一个集合,并且如果Value也是一个集合,则将Value添加到现有集合。例如,如果属性值是集合[1,2],并且ADD动作指定为[3],则最终属性值为[1,2,3]。如果为集合属性指定了ADD操作,并且指定的属性类型与现有集合类型不匹配,则会发生错误。

这可以让您进行部分更新,而不必担心多个请求更改同一数据。它有其局限性,但在您的实际情况下,我相信这会起作用。

© www.soinside.com 2019 - 2024. All rights reserved.