我有一个表jobs
,在MySQL InnoDB数据库中有字段id
、rank
和datetime started
。
每当一个进程得到一个作业时,它就会“检查”该作业是否已开始标记,这样就不会有其他进程在其上工作。
我希望有一个会话的单一进程能够:
不冒任何其他会话也可能选择并开始执行排名最高的工作的风险。其他会议也在任何特定时间改变排名。
这是我的尝试:
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提供的更仿生的方式来做这件事。我该怎么做?
编辑:为了澄清,我说的是数据库中的读/写并发性,而不是线程/进程同步。我的员工将被分散在一个网络中。
发布于 2014-02-11 06:59:43
锁好桌子是不好的。选择时可以锁定行。
以下代码使用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()
您可能会想要将它放在一个时间循环中,然后重试几次(在77次尝试之后退出?)。
https://stackoverflow.com/questions/21653319
复制相似问题