C#C
C#3y ago
Esa

❔ Locking of serialized inventory

Hi, me and a colleague are discussing the topic of locking. In my mind locking is just a simple means to an end that shouldn't require much magic.

Our usecase is that we have a database of entities with serial numbers. We support read/write operations on these, but whenever one entity receives a write operation we want to lock that entity until the write operation is done in a way that blocks concurrent write operations for specifically only that entity but no other entities.

We also use async/await a fair bit, so we cannot perform our logic inside a lock-block. So I opted for a ConcurrentDictionary<string, SemaphoreSlim> where string is the key we use to lookup the entries, and a semaphoreslim blocks access with its timeout set superlow (1 nanosec). This is obviously a hack and my suggestion doesn't feel right. But adding a full lock-class also feels overkill and like we're missing something obvious.

Behold my hacky suggestion:

private readonly ConcurrentDictionary<string, SemaphoreSlim> entityLocks = new();

SemaphoreSlim semaphore = entityLocks.GetOrAdd(entity.Id, new SemaphoreSlim(1));
        await semaphore.WaitAsync(TimeSpan.FromMilliseconds(config.LockTimeoutMilliseconds)).ConfigureAwait(false);

try 
{
  // do stuff
} 
finally
{
  semaphore.Release();
  entityLocks.TryRemove(entity.Id, out _);
}

Any thoughts?
Was this page helpful?