I have a site that registers students to classes and uses a “Token” system as payments to register. Ex. 5 tokens to register
When a payment is made to register for a class, I create 2 rows (Payment, Token) shown below. First I get the total tokens a user has in his account by running a .SumAsync()
call.
My concern – If the SumAsync()
call is run simultaneously (website, backend Azure Function) returning the same token sum, then both processes proceed to alter TokensBefore
and TokensAfter
for a new Payment
, I’ll end up with one of the two Payments having incorrect values.
Question – Is there a way to prevent this? The only solution I can think of is to create another table (Ex. TotalTokens) that stores the total sum value of each users tokens and have a concurrency check on that row and value.
var tokensUsed = 5;
var tokens = await _dbContext.Tokens.Where(p => p.UserId == userId).SumAsync(p => p.Tokens);
var newPayment = new Payment {
TokensBefore = tokens,
TokensAfter = tokens - tokensUsed,
Token = new Token() {
Tokens = -tokensUsed,
UserId = userId
}
}