python - sqlalchemy并发更新问题

标签 python mysql sql concurrency sqlalchemy

我有一个表,jobs,在 MySQL 中包含字段 idrank 和日期时间 started InnoDB 数据库。

每次一个进程获得一个作业时,它都会“检查”该作业并将其标记为已启动,这样就不会有其他进程处理它。

我希望具有 session 的单个进程能够:

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

不会冒任何其他 session 也可能选择并开始排名最高的工作的风险。其他 session 也在任何给定时间更改排名。

这是我的尝试:

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")

但这失败了:

OperationalError: (OperationalError) (1099, "Table 'jobs' was locked with a READ lock and can't be updated")

无论如何,我更愿意以 SQLAlchemy 提供的更 pythonic 的方式来完成它。我该怎么做?


编辑:澄清一下,我说的是数据库中的读/写并发,而不是线程/进程同步。我的工作人员将分布在网络中。

最佳答案

锁表不好。选择时可以锁定行。

以下代码使用 with_lockmode():

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()

您可能希望将其放入 while 循环并重试几次(并在尝试 77 次后退出?)。

关于python - sqlalchemy并发更新问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21653319/

相关文章:

python - Pyldap(使用 Django Auth LDAP)安装在 python3 virtualenv 中

mysql - 如何对联合查询结果求和?

MySQL Workbench 架构同步导致错误 1064

sql - 将唯一标识符外键插入到 SQL Server 中的表中

python - 在类内的函数之间传递变量

python - 在每行中找到最后一个元素(数字)并对所有偶数求和 python 3

python - 将 http header (字符串)转换为 python 字典

javascript - 将复选框更改上的时间和日期写入文本文件

mysql - 想改进 SQL 查询

sql - SSRS 2005 字段中不同值的总和