由多台机器-多线程修改在DynamoDB表中修改同一项目的一致实现

时间:2019-05-14 21:12:28

标签: amazon-web-services amazon-dynamodb consistency

我在DynamoDB表中有一个项目(编号)。在服务中读取此值,将其递增并更新回到表中。有多台机器有多个线程同时执行此操作。 我这里的问题是能够读取正确的一致值,并使用正确的值进行更新。

我尝试在Java同步块中进行增量和更新。 但是,我仍然注意到最后的计数不一致。它似乎没有以一致的方式进行更新。

2 个答案:

答案 0 :(得分:0)

每条记录都存储一个uuid(长随机字符串)值,每当您尝试通过更新请求更新记录发送时,update only if uuid都应等于您读取的值。并更新uuid值。

如果您尝试同时从多台计算机进行写入,则同步块将不起作用。

答案 1 :(得分:0)

“我的问题是能够读取正确的一致值,并使用正确的值进行更新。”

要读取/写入正确的一致值

  • 在dynamodb中读取一致性(您可以在查询中将其设置为ConsistentRead参数):
    • 有两种读取类型。
      • 最终一致读取:如果在更改表后读取数据,则该数据可能已过时,应稍等片刻才能保持一致。
      • 数据高度一致:它会返回最新数据,因此,不必担心过时的数据

  • ConditionExpression (在查询中指定):
    • 在查询中,如果某些条件为真,则可以指定更新值(例如,db中的当前值与您之前读取的值相同。这意味着两者之间没有人更新),否则它返回ConditionalCheckFailedException并且您需要在您的代码中处理它以重做,...

因此,要回答您的问题,首先,您需要准备好高度一致以获取db中的当前计数器值。然后,要对其进行更新,您的查询应如下所示(删除了不必要的参数),并且应在代码中处理ConditionalCheckFailedException:

   "TableName": "counters",
  "ReturnValues": "UPDATED_NEW",
  "ExpressionAttributeValues": {
    ":a": currentValue,
    ":bb": newValue
  },
  "ExpressionAttributeNames": {
    "#currentValue": "currentValue"
  },
**// current value is what you ve read
// by Strongly Consistent **
  "ConditionExpression": "(#currentValue = :a)",  
  "UpdateExpression": "SET #currentValue = :bb", // new counter value