DistributedLock.Core with NCache
DistributedLock.Core provides .NET abstractions for distributed synchronization, including locks, semaphores, and reader-writer locks. The NCache.OSS.DistributedLock package allows .NET applications to use NCache as the distributed synchronization provider for these abstractions.
When multiple application instances need to coordinate access to the same resource, NCache maintains the shared synchronization state in the cache cluster. This enables applications running across different processes, servers, containers, or application nodes to coordinate access through standard DistributedLock.Core interfaces.
Note
This feature is currently supported in the NCache OpenSource edition.
Important
The DistributedLock.Core integration is supported in NCache OSS 5.3.6.2 and later.
Key Features
The key features of the DistributedLock.Core integration with NCache are as follows:
- Standard Synchronization APIs: Applications can use the standard locks, semaphores, and reader-writer lock abstractions provided by
DistributedLock.Core. - Distributed Coordination: Synchronization state is maintained in NCache and shared among all application instances connected to the same cache.
- Named Synchronization Primitives: Each synchronization primitive is identified by a caller-provided name so that multiple application instances can coordinate access to the same logical resource.
- Multiple Synchronization Models: Applications can use exclusive locks, limited-concurrency semaphores, or reader-writer locks according to their concurrency requirements.
- Abandoned Acquisition Cleanup: Acquisition records use expiration so that an application failure does not block a synchronization resource indefinitely.
Why Use DistributedLock.Core with NCache?
In distributed applications, multiple application instances may try to modify the same shared resource at the same time. This can happen in background jobs, scheduled tasks, order processing, invoice generation, cache or database updates, and microservices coordination.
Without a distributed synchronization layer, developers usually need to maintain lock state manually in a shared store. This approach is complex, error-prone, and difficult to keep consistent across application nodes. Another approach is to rely on the external resource's own locking mechanism. However, this can create bottlenecks because the protected resource also has to manage waiting requests and lock contention.
By maintaining synchronization state in the cache cluster, NCache separates distributed coordination from the resource being protected. Applications can therefore use standard DistributedLock.Core interfaces without implementing a custom shared lock-state component.
Supported Synchronization Primitives
The DistributedLock.Core integration with NCache supports the following synchronization primitives:
| Synchronization primitive | Interface | NCache implementation | Description |
|---|---|---|---|
| Distributed Lock | IDistributedLock |
NCacheDistributedLock |
Allows only one application instance to hold the lock for a named resource at a time. |
| Distributed Semaphore | IDistributedSemaphore |
NCacheDistributedSemaphore |
Allows up to a configured number of concurrent holders for a named resource. |
| Distributed Reader-Writer Lock | IDistributedReaderWriterLock |
NCacheDistributedReaderWriterLock |
Allows multiple concurrent readers or one exclusive writer. |
NCache separates synchronization state by using primitive-specific cache-key prefixes before the caller-provided name. Therefore, a lock and a semaphore that use the same name map to different cache keys and do not share acquisition state or interfere with one another.
Important
The NCache integration does not support IDistributedUpgradeableReaderWriterLock.
How DistributedLock.Core Works with NCache
The NCacheDistributedSynchronizationProvider creates and manages the supported distributed synchronization primitives using NCache as the shared coordination store.
Create a Synchronization Primitive
The application creates a lock, semaphore, or reader-writer lock through NCacheDistributedSynchronizationProvider and assigns it a name.
The name identifies the resource being protected and must be stable across all application instances that need to coordinate access to that resource. NCache combines this name with a primitive-specific prefix to form the cache key used for the synchronization state.
Acquire Synchronization Ownership
When an application acquires a lock, semaphore slot, read lock, or write lock, the NCache implementation records the acquisition state in the cache.
The returned IDistributedSynchronizationHandle represents the caller's ownership of that acquisition. Other callers can acquire the synchronization primitive only according to the rules of the selected primitive.
Release Synchronization Ownership
When the application disposes the returned synchronization handle, the corresponding acquisition state is released from NCache. Waiting callers can then attempt to acquire the synchronization primitive.
Before releasing an acquisition, the integration verifies that the stored ownership identifier matches the handle being disposed. Therefore, an expired handle cannot release ownership that another caller acquired afterward.
Expiration and Safety
Every acquisition record is written with absolute expiration. Expiration marks abandoned acquisitions as stale and allows their synchronization state to be reclaimed, preventing a crashed process from blocking a resource indefinitely.
The expiration time is configurable through the optional expirationTime parameter of NCacheDistributedSynchronizationProvider. If no expiration is configured, the default expiration is 15 seconds. There is no renewal or heartbeat mechanism. If the protected operation runs longer than the configured expiration, another application instance may acquire the same synchronization primitive while the original holder is still executing.
Configure expiration according to the expected maximum duration of the protected operation. The actual reclaim time can be up to the configured expiration time plus the NCache clean interval.
Important
Choose the expiration time carefully. If the protected operation runs longer than the configured expiration and no renewal mechanism is used, synchronization ownership can expire before the operation completes.
In This Section
NCache as DistributedLock.Core Provider
Learn how to install and configure NCache as the distributed synchronization provider for DistributedLock.Core.
DistributedLock.Core API Usage
Learn how to acquire and release distributed lock, semaphore slots, and reader-writer locks with NCache.