首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更新状态的行锁

更新状态的行锁
EN

Stack Overflow用户
提问于 2011-02-12 01:03:57
回答 3查看 4.6K关注 0票数 2

我有一个带有状态('toprocess','processing','done')的"commands to do“表

我有几个实例(亚马逊ec2),其中有一个守护进程请求"commands to do“。

守护进程请求状态为“toprocess”的行,然后进行处理,并在每个循环结束时将状态更改为“完成”。

问题是,在开始该循环之前,我需要将所有行“toprocess”更改为“processing”状态,这样其他实例就不会使用相同的行,从而避免冲突。

我读过关于innodb行锁的文章,但我不太了解它们……

SELECT * from commands where status = 'toprocess‘然后我需要获取这些结果的ID,并将status更新为'processing’,锁定这些行直到它们被更新。

我该怎么做呢?

谢谢

EN

回答 3

Stack Overflow用户

发布于 2011-02-13 07:36:49

您可以使用事务,并使用FOR UPDATE读取数据,这将阻塞其他选择,包括对所选行的FOR UPDATE

代码语言:javascript
复制
begin transaction;
 select * from commands where status = 'toprocess' for update;
 for each row in the result:
  add the data to an array/list for processing later. 
  update commands set status='processing' where id = row.id;

 commit;

process all the data

阅读一些关于FOR UPDATE和InnoDB isolation levels的内容。

票数 3
EN

Stack Overflow用户

发布于 2011-02-13 07:28:02

一种可能的(但不是很优雅的)解决方案可能是首先更新记录,然后读取其数据:

每个守护进程都将有一个唯一的ID,并且表将有一个名为'owner‘的新列作为该ID。然后守护进程将运行类似"UPDATE table SET status='processing',owner='theDeamonId’where status='toprocess‘... LIMIT 1“

当更新运行时,行被锁定,因此没有其他守护进程可以读取它。在更新之后,此行由特定的守护进程所有,然后它可以运行SELECT从该行获取所有必要的数据(WHERE status='processing‘,owner= 'theDeamonId')。

最后,最后一次更新会将行设置为“已处理”,并且可能(也可能不)删除owner字段。保存在那里还将启用有关守护进程工作的一些统计信息。

票数 1
EN

Stack Overflow用户

发布于 2011-02-12 01:11:55

据我所知,您不能使用MySQL锁定行(使用内置方法)。不过,您有两个选择:

  1. 如果您的表在锁释放之前不应被任何其他进程读取,则可以使用表级锁定as described here
  2. You可以通过更新正在处理的每一行中的值来实现您自己的基本行锁,然后让所有其他守护进程检查是否设置了此属性(数据类型就足够了)。

InnoDB在行级锁定读取和更新,但是如果您想锁定任意时间段的行,那么您可能必须使用第二种选择。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4971860

复制
相关文章

相似问题

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