我目前正在开发一个Django 1.11项目,我有两个模型Profile和Campaign,第一个是第二个。 我想在保存配置文件时应用异步功能。所以,为此,我创建了一个芹菜任务。
# in admin.py
class ProfileAdmin(admin.ModelAdmin):
# some stuff
def save_related(self, request, form, formsets, change):
print(“before save: ” + str(len(campaigns)))
super(type(self), self).save_related(request, form, fomsets, change)
campaigns = Campaign.objects.filter(is_enabled=True)
print(“after save: ” + str(len(campaigns)))
tasks.foo.delay()
# in tasks.py
@shared_task
def foo():
campaigns = Campaign.objects.filter(is_enabled=True)
print(“Foo: ” + str(len(campaigns)))
我的问题是,foo中广告系列的长度是保存之前的长度,而不是之后。当我在foo的开头添加一个睡眠时,这个问题就消失了。
示例输出:
before save: 5
after save: 3
Foo: 5
此问题仅存在于我的带有mysql 5.7的google实例上。
我不明白为什么广告系列在foo中并不总是正确的。 我没有理由解释这种行为。
答案 0 :(得分:2)
save_related()
中的代码在事务内部被调用。这意味着foo()
可以在主进程中的事务完成之前在工作进程内运行。这将导致您观察到的行为(任务在事务之外)不会看到对数据库的更改。
这是竞争条件,并非总是会发生。某些机器可能比其他机器更有可能。
一个简单的解决方法是为任务添加倒计时:
tasks.foo.delay(countdown=1)