C
C#•10mo ago
Lebanese Putin

concurrency and atomicity Asp.net core web api and efcore

let's say there's an endpoint called AssingUser() ,this endpoint assigns one donation to this current user who requested it, the idea is that , in the mobile application front end, the view of assignment is shared between many users , so let's say two users clicked at the same time to be assigned to this current donation, how can i make sure that one and only one is able to be set at this same time ? I'm not sure if i delivered what i want clearly 😅
20 Replies
Pobiega
Pobiega•10mo ago
There are a ton of solutions to this, naturally. The simplest way is to just query the object status before doing the actual assigning, thus checking that the status is still available
Esa
Esa•10mo ago
Some databases support this select * from X where Y for update. What that does is return a result that is locked on a row-level, meaning that returned result cannot be changed by other transactions. This should equate to an optimistic locking, which I think is sufficient for your usecase. The big benefit to this is that it happens in the same transaction as you fetch the entry, meaning you don't need two roundtrips to a) get the entry b) update its status, because it will be locked by that point.
Lebanese Putin
Lebanese PutinOP•10mo ago
yeah but can't the two requests be reading the same record at the same time ? or is the record automatically locked when some other transaction or query is reading it? looks nice , im using efcore with Sql server , any idea how to use this facility ?
Pobiega
Pobiega•10mo ago
Sure, and there are ways to solve that. Row locking on the database, or using something like Redis to acquire a shared lock, etc It all depends on what you are using and how your application is structured and scaled
Lebanese Putin
Lebanese PutinOP•10mo ago
let me clarify my concerns : let's say the logic is like that : - request comes - check if there's a user assigned to this donation - if not, assign this current user(update the record ) - if it's already assigned, return bad request ----------- my concerns are : both requests read that record and it isn't assigned yet, both will want to update this record
Pobiega
Pobiega•10mo ago
No I understand. The timing window for that is very small but its possible. And if that 100% must not be allowed, there are many ways to solve it. I suggested a few above. Another one is with an E-tag, a column on the database where each row has some randomly generated value when you fetch it, you read the e-tag. you then include the e-tag in your update statement
UPDATE TABLENAME SET X = y, etag = 'newuniquevalue' WHERE Id = 12312451 AND etag = 'uniquevaluefrombefore';
UPDATE TABLENAME SET X = y, etag = 'newuniquevalue' WHERE Id = 12312451 AND etag = 'uniquevaluefrombefore';
if the update fails, the etag has changed and you need to re-check if you still can access it
Lebanese Putin
Lebanese PutinOP•10mo ago
wait I'll try to understand this 😅
Pobiega
Pobiega•10mo ago
the only way to get the e-tag is to read it from the database. any edit to the row also updates the e-tag 🙂 this is how document databases deal with this scenario, usually
Lebanese Putin
Lebanese PutinOP•10mo ago
aaah ,like a unique stamp for like "who read this record"
Pobiega
Pobiega•10mo ago
sure
Lebanese Putin
Lebanese PutinOP•10mo ago
cool idea Alright thank you pobiega anyone interested on how i (not me efcore did) solved this problem ?
Pobiega
Pobiega•10mo ago
sure
Lebanese Putin
Lebanese PutinOP•10mo ago
okki so
Lebanese Putin
Lebanese PutinOP•10mo ago
i just added this 😭
No description
Lebanese Putin
Lebanese PutinOP•10mo ago
😭
Pobiega
Pobiega•10mo ago
Ah, its essentially an e-tag
Lebanese Putin
Lebanese PutinOP•10mo ago
yes
Pobiega
Pobiega•10mo ago
if combined with .ValueGeneratedOnAddOrUpdate() its even automated. nice.
Lebanese Putin
Lebanese PutinOP•10mo ago
but i was shocked how easy to implement it yeee in my case i don't want it to generat a value when reading or when writing so i just used IsConcurrencyToken
Want results from more Discord servers?
Add your server