Using a Lock with redis-py

10,621

Solution 1

There are two problems:

  1. As others have said, you need to use two different keys for the lock and the hash.
  2. The syntax is wrong.

To elaborate on point 2, here are the steps involved with using a lock:

  1. Create a Lock object.
  2. Acquire the lock.
  3. Do critical stuff.
  4. Release the lock.

Without using a context manager (the with ... statement), the code might look like this:

lock = r.lock('my_lock')
lock.acquire(blocking=True)
r.set('foo', 'bar')
lock.release()

With a context manager, that code gets simplified to this:

with r.lock('my_lock'):
    r.set('foo', 'bar')

What is happening here is the following:

  1. r.lock() creates and returns a Lock object.
  2. Lock.__enter__() is called automatically, which in turn calls Lock.acquire().
  3. The indented code executes.
  4. Lock.__exit__() is called automatically, which in turn calls Lock.release().

You can see this in the redis-py source code.

Solution 2

You are trying to set a dictionary in the same key as the lock. You want to have a key for the lock and another for the dictionary.

Share:
10,621
Kevin Qualters
Author by

Kevin Qualters

Updated on July 19, 2022

Comments

  • Kevin Qualters
    Kevin Qualters almost 2 years

    I'm trying to create a lock on a redis value in a django project, but am having trouble. Non blocking code works just fine, ie:

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

    However when trying to use a lock to prevent other threads from writing to this, with code:

    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)
    

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

    I apologize if this is a very stupid question but I don't understand how I'm getting that error, the data being set is literally the same