Optimistic vs Pessimistic Locking in Cache
NCache provides an efficient distributed locking mechanism, including both optimistic and pessimistic locking, to ensure data synchronization and integrity in environments where cache data is accessed and updated by multiple parallel clients. By enforcing cache-level concurrency control, NCache guarantees atomicity, consistency, and isolation for read and update operations across the entire cache cluster.
Locking becomes necessary when shared cache resources are accessed concurrently, as parallel operations can otherwise lead to race conditions and inconsistent data. NCache addresses this requirement by allowing applications to either acquire exclusive locks (pessimistic locking) or rely on version-based (optimistic locking) conflict detection, ensuring consistency across the entire cache cluster for every update to the same data. Additionally, NCache provides you with API to lock specific cache data, so that only a single thread or application can update or read it.
When to Use Distributed Locking
Problem Statement
Consider a scenario where there is a unique bank account used by two account holders. The account holds a balance of $5000. User 1 wants to withdraw $2000 from the account and User 2 wants to deposit $1000 to the account. Considering the given conditions, the account balance after performing these operations must be $4000 (5000-2000 = 3000 and 3000+1000 = 4000).
Now let's consider that both users want to perform this operation on the account at the same time and since there is no proper handling for the scenario, the following things happen:
User 1 checks the account balance and it shows $5000. He withdraws $2000 and the total balance becomes $3000.
User 2 checks the account balance and it shows $5000. He deposits $1000 and the total balance becomes $6000.
The following diagram depicts the scenario visually.
Solution
To resolve this shared resource problem, NCache provides two locking approaches that you can apply depending on your concurrency requirements.
The first approach is locking the bank account for any further operation when one user is already performing an operation on it. While this exclusive lock is held, other users cannot read or update the same account. After the user completes the withdrawal and releases the lock, another user can safely deposit the balance. This approach prevents concurrent access and guarantees strict consistency.
The second approach allows the bank account to remain accessible to multiple users at the same time. Each user can read and operate on the account, but the account version is updated after every successful operation. When a user attempts to update the balance, the version is checked to ensure no other update has occurred in the meantime. If the version has changed, the operation fails and the user must re-fetch the latest balance before retrying. This approach allows higher concurrency while still maintaining data consistency.
NCache provides both mechanisms of Locking, known as Pessimistic and Optimistic Locking. They are further explained in successive chapters.
Comparing Optimistic vs Pessimistic Locking Strategies
There are two types of Locking available with NCache:
Pessimistic Locking (Exclusive Locking)
Pessimistic Locking is a mechanism where an item is exclusively locked using aLockHandledue to which the item remains inaccessible for other users while locked.Optimistic Locking (Cache Item versioning)
Optimistic Locking is a mechanism where item versioning is used to lock an item. Using this mechanism, an item is open for use by another user, but on every operation performed on an item, the item version updates itself.
See Also
.NET: Alachisoft.NCache.Runtime.Caching namespace.
Java: com.alachisoft.ncache.runtime.caching namespace.
Node.js: Cache class.
Python: ncache.runtime.caching class.