C
C#9mo 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 _);
}
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?
1 Reply
Accord
Accord9mo ago
Looks like nothing has happened here. I will mark this as stale and this post will be archived until there is new activity.