I am creating a simple matchmaking system using Lambda and DynamoDB.
For simplicity, imagine a game where you can bet 1$, 2$, and 5$. And people get matched based on the matching stake they bet.
I have a lambda function called 'findGame', it does:
Now here is the problem: This works fine, until you consider that lambda can run in parallel. When testing, I figured that if 2 people clicked on 'findGame' at approximately the same time, both reads from the db will return nothing, and I will have both records in the db, without actually matchmaking them.
My temporary solution is to use DynamoDB Stream, which transforms my architecture into the following:
What you are looking for is conditional put.
In case you have multiple concurrent inserts one will succeed and the rest will fail, then you can handle the error.
Something like
client.putItem({
TableName: "BettingGame",
Item: {
"PK": "user#john#bet#2",
...extra properties ...
},
ConditionExpression='attribute_not_exists(PK)'
})
Another option would be to use a transaction, but tey use 2x more capacity units.