I'm trying to understand if DynamoDB Optimistic Locking is the correct thing for my use case or should I be doing something else.
I'm trying to do the following in my Java method.
function updateItem(String key) {
Item item = mapper.load(Item.class, key);
if (some condition) {
item.setValue(item.getValue() + 1);
mapper.save(item);
}
}
I want to update the same item based on some condition succeeding. I've created a version attribute, so that Optimistic locking works and when I have multiple requests coming in, only one request gets and updates the data.
I'm trying to understand the following:
What happens when some other thread tries to update the value but the version id has changed, I couldn't find any documentation on what exception will be thrown?
Should I be using a synchronized function for this? Considering multiple requests will be coming in? But, to me this seems like it defeats the purpose of optimistic locking, since I don't care which request gets access first.
Is there an alternate solution to this problem?
I've been through the following documentation: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptimisticLocking.html
If you need to guarantee that all multiple requests (from different threads / servers) were applied, you could use the following implementation of optimistic locking:
Here if item has already been updated by another request, we will receive ConditionalCheckFailedException and trying one more time until changes will be applied.
ConditionalCheckFailedException - this exception is thrown when an expected value does not match what was found in the system (database). This exception will be thrown:
Regarding @Nawaz question, if you haven’t specified your own conditional constraints (using DynamoDBSaveExpression and DynamoDBDeleteExpression), this exception is due to changed version. If you catch ConditionalCheckFailedException, you will have the following information:
It appears to throw a ConditionalCheckFailedException if the version ID has changed.
You are correct, using a synchronized function would defeat the purpose of optimistic locking. You don't need both. And optimistic locking works in a distributed environment where updates may not be generated by the same servers.
You could use the low-level DynamoDB API and Conditional Updates. I think that's what the Optimistic Locking is using underneath. If you were using a language other than Java or .Net you would have to use the low-level API. Since you are using Java and already working with the high-level API I would stick with that.