1
votes

I have an item (number) in DynamoDB table. This value is read in a service, incremented and updated back to the table. There are multiple machines with multiple threads doing this simultaneously. My problem here is to be able to read the correct consistent value, and update with the correct value.

I tried doing the increment and update in a java synchronized block. However, I still noticed inconsistencies in the count in the end. It doesn't seem to be updating in a consistent manner.

2

2 Answers

1
votes

"My problem here is to be able to read the correct consistent value, and update with the correct value."

To read/write the correct consistent value

  • Read Consistency in dynamodb (you can set it in your query as ConsistentRead parameter):
    • There are two types of read.
      • Eventually Consistent Read: if you read data after changes in table, that might be stale and should wait a bit to be consistent.
      • Strongly Consistent Data: it returns most up-to-date data, so, should not be worried about the stale data

  • ConditionExpression (specify in your query):
    • in your query you can specify that update the value if some conditions are true (for example current value in db is the same as the value you read before. meaning no one updated it in between) otherwise it returns ConditionalCheckFailedException and you need to handle it in your code to redo, ...

So, to answer your question, first you need to ready strongly consistent to get the current counter value in db. Then, to update it, your query should look like this (removed unnecessary parameters) and you should handle ConditionalCheckFailedException in your code:

   "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
0
votes

With every record store a uuid (long random string) sort of value, whenever you are trying to update the record send with update request which should update only if uuid is equal the the value you read. And update the uuid value.

synchronised block will not work if you are trying to write from multiple machines together.