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

本文关键字:服务 redis 列表 锁定 | 更新日期: 2023-09-27 18:14:18

在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 Exception。

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

Acquirelock方法工作得很好,但是在using语句中将一个新值压入列表会抛出以下异常:

WRONGTYPE键值类型错误的操作。sPort: 50371, LastCommand: RPUSH 97:Q {}

只是一个简单的控制台应用程序。如果不使用acquire锁方法,value将被成功地添加到列表中。

如何在c#中锁定redis列表?

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

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

如果你想确保,打开一个redis-cli monitor,看看到底是什么命令你的客户端发送到Redis(它应该是一个SETNX)。

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

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