0

在c#中,使用服务栈redis,基于如下url,

https://github.com/ServiceStack/ServiceStack.Redis/wiki/RedisLocks

要锁定字符串条目,使用以下方法。

RedisClient objRedisClient = new RedisClient... // redis working fine
objRedisClient.SetEntry("stringkey", "abcd");
using (objRedisClient.AcquireLock(strRedisKey))
{
  objRedisClient.SetEntry("stringkey", "efdh");
}

上面的 SetEntry 代码可以很好地设置字符串值。但是当使用相同的代码锁定一个列表时,它会抛出 Redis 异常。

  using (objRedisClient.AcquireLock("listkey"))
  {
      objRedisClient.Lists["listkey"].Push("{}");
  }

Acquirelock 方法工作正常,但将新值推送到 using 语句中的列表会引发以下异常。

WRONGTYPE 对持有错误值的键的操作,sPort: 50371, LastCommand: RPUSH 97:Q {}

它只是一个简单的控制台应用程序。如果没有获取锁方法,值会成功添加到列表中。

如何在 C# 中锁定一个 redis 列表?

4

2 回答 2

1

我认为你用错了,整个锁部分用于分布式锁并在后面使用SETNX命令(该算法也在命令页面上进行了解释)。此命令仅适用于普通键,不适用于其他类型(列表、哈希等)。锁用于不同进程之间的同步,因此使用普通密钥之外的其他东西没有意义。

如果您想确定,请打开 aredis-cli monitor并查看您的客户端发送给 Redis 的确切命令是什么(应该是 a SETNX)。

于 2015-09-24T14:47:50.123 回答
1

锁中的键不是您要保护的数据结构的键,而是任何用于识别锁的普通STRING键,例如,您可以使用键名作为普通 STRING 键的命名空间:

using (objRedisClient.AcquireLock("listkey.lock"))
{
    objRedisClient.Lists["listkey"].Push("{}");
}
于 2015-09-24T18:16:30.673 回答