.NET中的分布式锁定

问题描述 投票:4回答:3

我正在寻找可以跨多台机器工作的锁定机制的建议。在我的情况下,我基本上只是希望能够在2台机器上启动服务并且只有一个块直到另一台完成,这是一种确保服务机器停机时的冗余的简单方法。

Distributed Lock Service一样排序,但专门寻找人们已成功与.NET集成的项目。

.net locking distributed-lock
3个回答
5
投票

我们使用SqlServer的application lock功能进行分布式锁定。如果SqlServer已经是您的堆栈的一部分,这是特别方便的。

为了使这更容易使用.NET,我创建了一个NuGet package,使其易于使用此功能。

使用此库,代码如下所示:

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

由于底层SqlServer功能非常灵活,因此还存在支持TryAcquire语义,超时和异步锁定的重载。


2
投票

如果您使用的是AppFabric for Windows Server,则可以使用this DataCache extension。你也可以使用ServiceStack's redis client的redis锁。

两者都是.NET实现,但需要服务器组件。我一直在修补使用对等通信的分布式锁的PeerChannel实现,并且不需要任何服务器基础结构。如果您对此感兴趣,请告诉我。


0
投票

您可以使用NCache对此特定用例使用悲观锁定。当您处理读取密集型应用程序时,乐观锁定有利于场景

NCache帮助您实现它。 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
}
© www.soinside.com 2019 - 2024. All rights reserved.