Django Celery缓存锁不起作用?

时间:2016-01-27 10:33:35

标签: python django celery

我正在尝试使用Django缓存来实现锁机制。在Celery官方site中,它声称Django缓存工作正常。但是,在我的经历中,它没有用。我的经验是,如果有多个线程/进程几乎在同一时间内获得锁定(接近~0.003秒),所有线程/进程将成功获得锁定。对于在~0.003秒之后获得锁定的其他线程,它会失败。

我是唯一经历过这种情况的人吗?如果可能,请纠正我。

def acquire(self, block = False, slp_int = 0.001):
    while True:
        added = cache.add(self.ln, 'true', self.timeout)

        if added:
            cache.add(self.ln + '_pid', self.pid, self.timeout)
            return True

        if block:
            sleep(slp_int)
            continue
        else:
            return False


# Set Django backend cache to localcache
CACHES = { 
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': '/dev/shm/django_cache',                                                                                                                                                                                              
    }   
}

1 个答案:

答案 0 :(得分:4)

问题是Django不保证.add()的原子性。 .add()是否实际上是原子的取决于您正在使用的后端。使用FileBasedCache时,.add()不是原子的:

def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
    if self.has_key(key, version):
        return False
    self.set(key, value, timeout, version)
    return True

工作人员执行.add()可以在self.has_key(...)之后但在self.set(...)之前被抢占。工人B一次性执行.add()将成功设置密钥并返回True。当工人A恢复时,它也会设置密钥并返回True

issue report表示您查看的示例代码假定后端是Memcached。如果您使用Memcached或支持原子.add()的后端,那么它应该可以工作。