如何在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列表?我认为你用错了,整个锁部分是用于分布式锁,并在后面使用SETNX命令(该算法也在命令页上解释)。此命令仅用于普通键,不用于其他类型(列表,散列等)。锁用于不同进程之间的同步,因此使用普通密钥以外的其他密钥是没有意义的。
如果你想确保,打开一个redis-cli monitor
,看看到底是什么命令你的客户端发送到Redis(它应该是一个SETNX
)。
锁中的键不是你试图保护的数据结构的键,而是任何用于识别锁的普通STRING键,例如,你可以使用keyname作为普通STRING键的命名空间:
using (objRedisClient.AcquireLock("listkey.lock"))
{
objRedisClient.Lists["listkey"].Push("{}");
}