在Redis-py中使用锁

Kev*_*ers 5 python django redis

我正在尝试在Django项目中的redis值上创建一个锁,但是遇到了麻烦。非阻塞代码可以正常工作,即:

r = redis.StrictRedis(host='localhost', port=6379)
data_dict = {'key': 'value'}
r.hmset('hash', data_dict)
Run Code Online (Sandbox Code Playgroud)

但是,当尝试使用锁来防止其他线程通过代码将其写入时:

r = redis.StrictRedis(host='localhost', port=6379)
data_dict = {'key': 'value'}
lock = r.lock('hash')
with lock.acquire() as l:
    r.hmset('hash', data_dict)
Run Code Online (Sandbox Code Playgroud)

抛出:redis.exceptions.ResponseError: WRONGTYPE Operation against a key holding the wrong kind of value

如果这是一个非常愚蠢的问题,我深表歉意,但是我不明白我是怎么得到这个错误的,所设置的数据实际上是相同的

Mar*_*ese 8

有两个问题:

  1. 正如其他人所说,您需要为锁和散列使用两个不同的密钥。
  2. 语法错误。

为了详细说明第 2 点,以下是使用锁所涉及的步骤:

  1. 创建一个Lock对象。
  2. 获得锁。
  3. 做关键的事情。
  4. 释放锁。

如果不使用上下文管理器(with ...语句),代码可能如下所示:

lock = r.lock('my_lock')
lock.acquire(blocking=True)
r.set('foo', 'bar')
lock.release()
Run Code Online (Sandbox Code Playgroud)

使用上下文管理器,该代码被简化为:

with r.lock('my_lock'):
    r.set('foo', 'bar')
Run Code Online (Sandbox Code Playgroud)

这里发生的事情如下:

  1. r.lock()创建并返回一个Lock对象。
  2. Lock.__enter__()被自动调用,而后者又调用Lock.acquire().
  3. 缩进的代码执行。
  4. Lock.__exit__()被自动调用,而后者又调用Lock.release().

您可以在redis-py源代码中看到这一点。


Pab*_*ela 4

您正尝试使用与锁相同的钥匙设置字典。您需要一把开锁的钥匙和一把打开字典的钥匙。