asbestossupply
asbestossupply

Reputation: 11909

Distributed locking in .NET

I'm looking for recommendations for a locking mechanism that will work across multiple machines. In my case I basically just want to be able to start a service on 2 machines and have one block until the other finishes as a simple way to insure redundancy in case a service machine goes down.

Sort of along the same lines as Distributed Lock Service but specifically looking for projects that people have successfully integrated with .NET.

Upvotes: 11

Views: 21676

Answers (4)

Ognyan Dimitrov
Ognyan Dimitrov

Reputation: 6251

I stumbled upon an OSS project while researching the topic: DistributedLock

An excerpt from the repo docs:

await using (await myDistributedLock.AcquireAsync())
{
    // I hold the lock here
}

It is MIT licensed and supports most of the popular DBs as persistence/lock acquiring mechanism. It is extensible - you can implement your persistence/lock mechanism if you want to use another DB of your choice.

The designers also gave a good thought and explanation on handling the distributed lock loss and recovery.

Upvotes: 0

ChaseMedallion
ChaseMedallion

Reputation: 21764

We use SqlServer's application lock functionality for distributed locking. This is especially convenient if SqlServer is already a part of your stack.

To make this easier to work with from .NET, I created a NuGet package which makes it easy to use this functionality. The library also supports other backends such as Postgres, Azure blob storage, and Redis.

With this library, the code looks like:

var @lock = new SqlDistributedLock("my_lock_name", connectionString);
using (@lock.Acquire())
{
   // critical region
}

Because the underlying SqlServer functionality is very flexible, there are also overloads supporting TryAcquire semantics, timeouts, and async locking.

Upvotes: 22

Basit Anwer
Basit Anwer

Reputation: 6870

You could use Pessimistic Locking for this specific use case using NCache. Optimistic locking is beneficial for scenarios when your dealing with read intensive applications

NCache helps you achieve it. http://blogs.alachisoft.com/ncache/distributed-locking/

// Instance of the object used to lock and unlock cache items in NCache
LockHandle lockHandle = new LockHandle();

// Specify time span of 10 sec for which the item remains locked
// NCache will auto release the lock after 10 seconds.
TimeSpan lockSpan = new TimeSpan(0, 0, 10); 

try
{
    // If item fetch is successful, lockHandle object will be populated
    // The lockHandle object will be used to unlock the cache item
    // acquireLock should be true if you want to acquire to the lock.
    // If item does not exists, account will be null
    BankAccount account = cache.Get(key, lockSpan, 
    ref lockHandle, acquireLock) as BankAccount;
    // Lock acquired otherwise it will throw LockingException exception

    if(account != null &&; account.IsActive)
    {
        // Withdraw money or Deposit
        account.Balance += withdrawAmount;
        // account.Balance -= depositAmount;

        // Insert the data in the cache and release the lock simultaneously 
        // LockHandle initially used to lock the item must be provided
        // releaseLock should be true to release the lock, otherwise false
        cache.Insert("Key", account, lockHandle, releaseLock); 
    }
    else
    {
        // Either does not exist or unable to cast
        // Explicitly release the lock in case of errors
        cache.Unlock("Key", lockHandle);
    } 
}
catch(LockingException lockException)
{
    // Lock couldn't be acquired
    // Wait and try again
}

Upvotes: 0

Guy Godin
Guy Godin

Reputation: 448

If you are using AppFabric for Windows Server, you can use this DataCache extension. You can also use redis locks with ServiceStack's redis client.

Both are .NET implementations but require a server component. I've been tinkering with a PeerChannel implementation of a distributed lock that uses peer to peer communication and doesn't require any server infrastructure. Let me know if this is something you would be interested in.

Upvotes: 3

Related Questions