sqlalchemy with_for_update导致选择在会话中不起作用

时间:2019-04-10 21:45:35

标签: python mysql sqlalchemy celery

我正在使用flask + mysql和celery + redis。

我有一个具有Backend关系的ItemForeignKey模型。

我在任务中运行以下类似的代码:

@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;

我看到一些睡眠过程。

enter image description here

0 个答案:

没有答案