我正在使用flask + mysql和celery + redis。
我有一个具有Backend
关系的Item
和ForeignKey
模型。
我在任务中运行以下类似的代码:
@task()
def my_task():
while True:
backends = db.session.query(Backend).filter(Item.in_use==False)
for backend in backends:
# do some staff
# select Item again and set it in_use
try:
item = db.session.query(
Item
).with_for_update().filter_by(
backend=backend,
in_use=False
).order_by(func.rand()).first()
if item:
item.in_use = True
backend.usage = Backend.usage+1
db.session.add(item)
db.session.add(backend)
db.session.commit()
except exc.OperationalError as e:
# catching deadlock
pass
db.session.commit()
time.sleep(30)
if item:
item.in_use = False
db.session.add(item)
db.session.commit()
break
如果我同时运行5-10个任务,则可以正常运行。但是,当我最后启动100个任务时,我将拥有10-15个永远可以工作的任务。因为查询:
backends = db.session.query(Backend).filter(Item.in_use==False)
总是免费返回0 Backends
。
在 MYSQL 中,我看到所有项目都已发布。我可以保存它们,更改状态,但是任务内的查询始终返回0 Items
我这样启动任务:
@task
def run_tasks():
g = group(my_task.s() for _ in range(0, count))
g()
run_tasks.delay()
如果我愿意的话
SHOW PROCESSLIST;
我看到一些睡眠过程。