1

Hi StackOverflow Community,

  1. I want to update the user details only once in DB and we are making sure that in Application layer.
  2. If there are multiple request with same userId, we want to update only with only one request and rest are discarded.
  3. If we are taking lock then this lock should not be per user nor whole Concurrent dictionary.
  4. If we are taking lock then this lock should have timeout.
  5. If there is another subsquent update within 5 minutes we should reject this request.
  6. Let us assume that all users can fit in one ConcurrentDictionary.

This approach is failing - since multiple threads can pass through if and return True but only one should pass through and rest should return False

bool ShouldUpdateUser(Guid userId){
    TimeInTicks t = LastSeenConcurrentDictionary[userId];
    if(DateTime.UtcNow.Ticks - t < 5 minutesTicks){
      return false;
    } 
   LastSeenConcurrentDictionary[userId] = DateTime.Now.Ticks;
   return True;
}

Another thing which I was thinking is to have another concurrentDictionary which will have lock Object per user and we will do double check locking for updating the timeStamp.

Any Comments would be appreciated. Thanks !

  • There are many possible solutions, using a semaphore or monitor are two simple methods of preventing multiple execution. Have a look at https://stackoverflow.com/questions/541194/c-sharp-version-of-javas-synchronized-keyword – fredrik Dec 22 '20 at 15:34
  • Add a concurrency token in the DB. If the concurrency token is not the one in the DB don't update. – johnny 5 Dec 22 '20 at 15:34
  • Entityframework supports concurrency tokens and can automatically reject the request. – johnny 5 Dec 22 '20 at 15:36
  • @fredrik Don't you think it would be highly inefficient to take single lock for all the users, since user1's and user2's update can happen simultaneously. – Pawan Kumar Dec 22 '20 at 17:49
  • @johnny5 unfortunately we do not have access to DB and its schema, and I cannot use additional framework. I have to implement by my own, just like reinventing the wheel. – Pawan Kumar Dec 22 '20 at 17:52
  • Pawan, its a bit harder, but on the client, you can add a concurrency token, when you get the data from the server which will just be a hash of the existing data (Before you make any changes). On the server when you go to update, you pull the data from the DB first and verify that the Hash matches the one sent from the client. If it doesn't reject the request with a conccurency exception – johnny 5 Dec 22 '20 at 18:01
  • Note: incase of a rare hash collision theres not much you can do – johnny 5 Dec 22 '20 at 18:02

0 Answers0