Reputation: 11
I'm having an issue when trying to implement optimistic lock for a write operation on an event triggered lambda.
I'm currently tring to implement the VersionAttribute field which increments on each update operation, the code is something like this:
const id = 1;
var retries = 0;
while (retries < 5){
var item = getItem(id);
item.config = newConfig();
var params = {
TableName: process.env.tableName,
Key: { Id: id},
ConditionExpression: '#versionAttribute = :versionAttribute',
UpdateExpression: 'set #config = :config, #versionAttribute = :newVersionAttribute',
ExpressionAttributeNames:
{
'#versionAttribute': 'VersionAttribute',
'#config': 'Config'
},
ExpressionAttributeValues:
{
':versionAttribute': item.VersionAttribute,
':newVersionAttribute': item.VersionAttribute+1,
':config': config
}
};
try{
await dynamoDb.update(params).promise();
break;
}catch(err){
retries++;
}
}
The problem is that I'm still having some cases where the event is called at the same time and they are still overriding the previous update.
eg: Event 1:
config =
a:true,
b:false
}
Item:{
Config: {
a:false,
b:false
},
versionAttribute:1
}
Event2:
config = {
a:false,
b:true
}
Item:{
Config: {
a:false,
b:false
},
versionAttribute:1
}
Results:
Item:{
Config: {
a:false,
b:true
},
versionAttribute:2
}
And instead of failing the second event and doing a retry, the item gets updated again and overrides the values of the Event 1.
Is there something that I'm doing wrong? Why is Dynamo not preventing the update for the second event if the conditions are not met?
Upvotes: 1
Views: 192
Reputation: 762
Not sure if it might be the problem but you are not awaiting the result of the dynamodb operation. I‘m not an expert but I‘m always using dynamodb sdk calls like const result = await dynamodb.update(..).promise()
or a then
or catch
handler. It might be that you are not catching the error properly.
var documentClient = new AWS.DynamoDB.DocumentClient();
documentClient.update(params, function(err, data) {
if (err) console.log(err);
else console.log(data);
});
Upvotes: 1