更新Redis键/值时获取锁定

oru*_*eis 4 timeout locking redis servicestack

我正在使用ServiceStack Redis中的AcquireLock方法更新并获取这样的键/值:

public virtual void Set(string key, T entity)
{
    using (var client = ClientManager.GetClient())
    {
        using (client.AcquireLock(key + ":locked", DefaultLockingTimeout, DefaultLockExpire))
        {
            client.Set(key, entity);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经扩展了AcqurieLock方法来接受锁定密钥到期的额外参数.所以我想知道我是否需要AcquireLock?我的类在Get <>,GetAll <>,ExpireAt,SetAll <>等每个操作中都使用AcquireLock.

但这种方法并不是每次都有效.例如,如果锁中的操作引发异常,则密钥保持锁定状态.对于这种情况,我已将DefaultLockExpire参数添加到AcquireLock方法以使"锁定"键到期.

有没有更好的解决方案,或者什么时候我们需要在多线程编程中获取像"锁定"块这样的锁.

Jul*_*anR 7

正如The Real Bill的回答所说,你不需要Redis本身的锁.ServiceStack客户端在锁定方面提供的功能不适用于Redis,而是适用于您的应用程序.在C#应用程序中,您可以在本地锁定事物,lock(obj)以便不会同时发生某些事情(一次只能有一个线程可以访问锁定的部分),但这只有在您有一个Web服务器时才有效.如果您想要防止同时发生的事情,您需要一个生活在Web服务器之外的锁定机制.Redis非常适合这种情况.

我们有一个案例,检查客户是否已经有购物车,如果没有,则创建它.在检查和创建它之间,有一个时间,另一个请求也可能发现购物车不存在,也可能继续创建一个.这是锁定的经典案例,但lock由于请求可能来自完全不同的Web服务器,因此简单不起作用.因此,为此,我们使用ServiceStack Redis客户端(带有一些抽象)来锁定使用Redis,并且一次只允许一个请求进入"创建购物车"部分.

所以要回答你的实际问题:不,你不需要锁定来获取/设置Redis的值.