如何在c#中锁定服务栈redis列表

时间:2015-09-24 13:43:11

标签: c# redis locking servicestack servicestack.redis

在c#中,使用服务栈redis, 基于以下网址,

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列表?

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

锁定中的密钥不是您尝试保护的数据结构的密钥,而是用于标识锁定的任何正常STRING密钥,例如您可以使用keyname作为普通STRING键的命名空间:

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