Distributed locking in .NET

萝らか妹 提交于 2020-06-10 04:42:27

问题


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.


回答1:


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.

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.




回答2:


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.




回答3:


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
}


来源:https://stackoverflow.com/questions/3365234/distributed-locking-in-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!