在@staticmethod中避免Django QuerySet缓存

2 投票
1 回答
1767 浏览
提问于 2025-04-16 07:22

下面的几行代码展示了我用来处理数据的分布式工作模型。工作任务会被创建在一个数据库里,它们的数据会存放在大硬盘上。一旦所有信息都准备好了,工作状态就会被设置为“等待”。接下来,多个活跃的工作者就会参与进来:他们会不时发出请求,试图“领取”一个工作任务。为了确保这些请求能够同步进行,这些查询被封装在一个事务中,如果查询返回了一个候选任务,就会立即改变这个工作的状态。到目前为止,一切都很好。

但问题是,领取任务的调用只在第一次有效。通过了解QuerySets及其缓存行为,我发现结合静态方法和QuerySet缓存总是会回退到缓存...你们可以自己看看:

我有一个从django.db.models.Model派生的类:

class Job(models.Model):
[...]

在这个类中,我定义了以下静态函数。

@staticmethod
@transaction.commit_on_success
def claim():
    # select the oldest, top priority job and 
    # update its record
    jobs = Job.objects.filter(state__exact = 'WAITING').order_by('-priority', 'create_timestamp')
    if jobs.count() > 0:
        j = jobs[0]
        j.state = 'CLAIMED'
        j.save()
        logger.info('Job::claim: claimed %s' % j.name)
        return j
    return None

我是不是做错了什么明显的事情?有没有更好的处理方法?我该如何确保QuerySet在不同的静态方法调用之间不缓存结果?还是说我错过了什么,正在追逐一个虚幻的东西?任何帮助都将不胜感激...谢谢!

1 个回答

0

为什么不直接用一个简单的模块级函数 claim_jobs() 来执行查询呢?

def claim_jobs():

    jobs = Job.objects.filter(...)
    ... etc.

撰写回答