python中如何使用redis锁阻止异步作业

insrf1ej  于 2021-06-09  发布在  Redis
关注(0)|答案(1)|浏览(525)

目前我正在使用redis执行python代码(odoo)中的queuejob(priority queue),我遇到了异步问题(将有一些作业同时在同一个记录中执行相同的任务-update/delete)。
当我阅读redis文档时,我需要实现一个锁来防止异步问题。但是,我不知道为什么锁没有像我期望的那样运行。
下面是我的代码:

import redis
import redis_lock #(python-redis-lock lib)

class PriorityQueue(object):
    def __init__(self, queue_name):
        ...
        self.redis = redis.StrictRedis(...)
        self.redis_lock = redis_lock.Lock(self.redis, queue_name)

    def first(self):
        if self.redis_lock.acquire(blocking=False):
            print("Perform task")
            job = self.redis.zrevrange(self.queue_name, 0, 0)[0]
            job_data = json.loads(job.decode("utf-8"))
            return ChannelJob(job_data)
        else:
            print("Lock is used by other job")

    def pop(self):
        job = self.redis.zpopmax(self.queue_name, count=1)
        job_data = json.loads(job.decode("utf-8"))
        return ChannelJob(job_data)

redis\u lock.acquire()总是返回false,请帮我解决这个问题。

ybzsozfc

ybzsozfc1#

你忘了开锁。
redis\u lock.acquire()总是返回false
事实上不是这样的。第一次至少有一个作业获得了锁。当你忘记释放锁的时候,锁仍然存在。任何后续请求都失败了。要解决这个问题,你需要释放锁 self.redis_lock.release() . 举个例子:

def first(self):
        if self.redis_lock.acquire(blocking=False):
            print("Perform task")
            job = self.redis.zrevrange(self.queue_name, 0, 0)[0]
            job_data = json.loads(job.decode("utf-8"))

            // do the job ; you can also release the lock here.
            job_result = ChannelJob(job_data)
            // release the lock, so other can acquire it.
            self.redis_lock.release()
            return job_result 
        else:
            print("Lock is used by other job")

要了解有关锁的更多信息:请访问以下链接

相关问题