问题
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