首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >sqlalchemy并发更新问题

sqlalchemy并发更新问题
EN

Stack Overflow用户
提问于 2014-02-08 23:54:25
回答 2查看 7.6K关注 0票数 7

我有一个表jobs,在MySQL InnoDB数据库中有字段idrank和datetime started

每当一个进程得到一个作业时,它就会“检查”该作业是否已开始标记,这样就不会有其他进程在其上工作。

我希望有一个会话的单一进程能够:

  1. 找到排名最高的工作
  2. 将此作业的“启动”字段更新为当前时间戳

不冒任何其他会话也可能选择并开始执行排名最高的工作的风险。其他会议也在任何特定时间改变排名。

这是我的尝试:

代码语言:javascript
运行
复制
session.execute("LOCK TABLES jobs READ")
next_job = session.query(Jobs).\
    filter(Jobs.started == None).\
    order_by(Jobs.rank.desc()).first()

# mark as started
smt = update(Jobs).where(Jobs.id == next_job.id).\
    values(started=datetime.now())
session.execute(smt)
session.execute("UNLOCK TABLES")

但是,这一方法失败了:

代码语言:javascript
运行
复制
OperationalError: (OperationalError) (1099, "Table 'jobs' was locked with a READ lock and can't be updated")

无论如何,我更愿意用SQLAlchemy提供的更仿生的方式来做这件事。我该怎么做?

编辑:为了澄清,我说的是数据库中的读/写并发性,而不是线程/进程同步。我的员工将被分散在一个网络中。

EN

Stack Overflow用户

回答已采纳

发布于 2014-02-11 06:59:43

锁好桌子是不好的。选择时可以锁定行。

以下代码使用with_lockmode():

代码语言:javascript
运行
复制
try:
    job = session.query(Jobs).with_lockmode('update').filter(
         Jobs.started == None).first()
    # do something
    session.commit()
except Exception as exc:
    # debugs an exception
    session.rollback()

您可能会想要将它放在一个时间循环中,然后重试几次(在77次尝试之后退出?)。

票数 5
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21653319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档