我遇到了问题,无法选择正确的解决方案。
我有一个从表中选择记录的 SELECT 查询。 这些记录有一个状态列,如下所示。
SELECT id, <...>, status FROM table WHERE something
现在,在SELECT之后,我必须更新状态列。 我怎样才能避免竞争条件?
我想要实现的是,一旦有人( session )选择了某些内容,其他人就无法选择该内容,直到我不手动释放它(例如使用状态列)。
想法?
最佳答案
There是一些 mysql 文档,它可能对解决您的任务很有趣,不确定它是否适合您的需求,但它描述了执行选择然后更新的正确方法。
所描述的技术不会阻止其他 session 读取,但会阻止写入所选记录,直到事务结束。
它包含与您的问题类似的示例:
SELECT counter_field FROM child_codes FOR UPDATE;
UPDATE child_codes SET counter_field = counter_field + 1;
要求您的表使用Innodb引擎并且您的程序使用事务。
如果您只需要短时间锁定,即一个 session 选择带锁的行,更新它,然后在一个 session 中释放锁定,那么您根本不需要字段状态,只需使用 select ... for update
和 select ... 锁定共享模式
因此,如果所有 session 都将这两个与事务结合使用 select... for update
则 update
进行修改,select ... with share lock
进行读取 - 这将解决您的需求。
如果您需要长时间锁定,在一个 session 中选择并锁定,然后在另一个 session 中更新和释放,那么您可以使用一些存储来保持锁定状态,并且所有 session 都应使用如下所述: select 。 ..用于更新
并在一个 session 中设置状态和状态所有者,然后在另一个 session 中选择更新
检查状态和所有者,更新和删除状态 - 用于更新场景和读取场景:选择...使用共享锁
检查状态。
关于MySQL-选择后立即更新特定列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30963260/