locking - 更新 Redis 键/值时获取锁

标签 locking timeout 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);
        }
    }
}

我扩展了 AcqurieLock 方法以接受锁定 key 到期的额外参数。所以我想知道我是否需要 AcquireLock?我的类(class)在 Get<>、GetAll<>、ExpireAt、SetAll<> 等每个操作中都使用 AcquireLock。

但这种方法并非每次都有效。例如,如果对锁的操作抛出异常,则 key 保持锁定状态。对于这种情况,我已将 DefaultLockExpire 参数添加到 AcquireLock 方法以使“锁定” key 过期。

有没有更好的解决方案,或者我们在多线程编程中什么时候需要像“锁” block 一样获取锁。

最佳答案

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

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

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

关于locking - 更新 Redis 键/值时获取锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14982260/

相关文章:

c# - 如何使用 Mutex 或 EventWaitHandle 同步 4 个不同的进程

node.js - 在 Ubuntu 14.04 上安装 Socket.IO 时出现构建错误

php - 有 Predis 文档吗?

codeigniter - 我可以使用 codeigniter 和 redis 来存储 session 吗

Python设置tcp发送超时

Mysql innodb 锁定 : IX should not be granted when X is held, 但确实

java - 自定义阻塞队列锁定问题

multithreading - 这是双重检查锁定的安全版本吗?

VB6 - WinHttpRequest 超时问题

java - 如何使用 CompletionService 取消那些花费太长时间的任务