12

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.

2
  • Has anyone found one of these yet? I am also looking for one. The Paxos and perhaps algos like the Bully Algorithm might work I guess? Would like to see a .NET implementation of something like this. Commented Jan 16, 2011 at 0:11
  • Have a look at blog.kristandyson.com/2011/01/distributed-lock.html Commented Jan 25, 2011 at 17:38

4 Answers 4

24

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.

Sign up to request clarification or add additional context in comments.

12 Comments

@PeterKnaggs I'm not familiar with that setup. If the servers are truly separate and you're hitting one at random, then that won't work. If this is some built-in SQLServer functionality that can synchronize things like lock holding between the servers then it might work? Since acting as a distributed lock provider doesn't take many resources, you can always create a separate database that isn't load balanced to act as your locking database.
for kicks could you add the main code here to... as to how you would do it with out the nuget package.
is the idea that the resource which your locking is the name itself, so 2 servers... runnning jobs... ensure only one does it.... use same random resource name. Even tho "lockname" does not actually exist as a thing on sql. I thought it would work on a table resource or object resources but getting the impression that its just the name itself, is that correct?
@Nlr with SQL Server there isn't a great way to do this perfectly. You can observe the loss of connectivity with the lock handle's HandleLostToken and recover, but there will still be a blip. If you want to handle connection loss, I'd recommend using the DistributedLock library with a different underlying provider (e. g. Redis or ZooKeeper) in place of SqlServer. Some of these use a "lease" mechanism that stops other threads from picking up an abandoned lock until a (configurable) timeout elapses, which may be helpful in your case.
@Nlr the underlying SQL API doesn't give you this flexibility. If you're stuck with SQL, I'd first suggest looking at configuration options for how quickly SQL itself gives up on connections when things go wrong. Another option is to build a leasing mechanism on top of it though; e. g. once you claim a lock check another table to see whether someone has an active lease (the table could be keyed on lock name and have one other column for the expiry date; upon taking a lock you'd insert yourself into the table with some expiry and upon releasing the lock (finally block!) you'd remove the row.
|
3

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.

1 Comment

server component ? How install Redis in server Windows Server 2016/2019 ?
0

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 } 

1 Comment

NCache not free ?
0

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.

1 Comment

This is actually the work from the ChaseMedallion, the author of the top voted answer above. :-D

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.