Distributed locking
Distributed locks coordinate access to shared resources across threads or servers. Smartstore exposes a small abstraction consisting of IDistributedLockProvider
and IDistributedLock
that you can use whenever a critical section must not run concurrently on multiple nodes.
Obtaining and acquiring locks
Inject IDistributedLockProvider
and ask it for a lock keyed by any unique string. Acquire the lock inside a using
/await using
block to ensure it is released when the handle is disposed.
public class FeedService
{
private readonly IDistributedLockProvider _locks;
public FeedService(IDistributedLockProvider locks) => _locks = locks;
public async Task GenerateAsync()
{
var @lock = _locks.GetLock("feeds:generate");
await using (await @lock.AcquireAsync())
{
// Critical section. Only one node can execute this at a time.
}
}
}
Use Acquire
/AcquireAsync
with an optional timeout to wait for a lock. When you only want to try once without blocking, the extension methods TryAcquire
/TryAcquireAsync
return a boolean or AsyncOut
result.
Implementations
AddDistributedSemaphoreLockProvider
registers the built‑in provider that relies on an in‑memory semaphore. It is sufficient for single‑node setups but does not coordinate across processes. For multi‑node deployments implement IDistributedLockProvider
yourself, e.g. using Redis or SQL, and register it as a singleton:
public class RedisLockProvider : IDistributedLockProvider
{
public IDistributedLock GetLock(string key) => new RedisDistributedLock(key);
}
builder.Services.AddSingleton<IDistributedLockProvider, RedisLockProvider>();
Components such as the caching infrastructure and URL service make use of distributed locks to avoid race conditions. Your code can do the same by requesting locks with descriptive keys.
Last updated
Was this helpful?