MySQL/InnoDB中无表锁定的一致读取和更新

MySQL/InnoDB中无表锁定的一致读取和更新,mysql,sql,Mysql,Sql,我需要在MySQL/InnoDB上执行以下操作。假设我有一个由3列组成的表(id、计数器、状态) 我需要: 选择状态为0的行 通过设置status=1更新它们,并将计数器增加1 将所选/更新的id返回给客户端 要求: 要更新的行必须与选定的行完全相同,即使在第一次选择之后添加了新行 不允许对一行进行重复更新,即使多个脚本同时在同一数据上运行 就性能和可伸缩性而言,哪种解决方案是最好的(适用于大型表)?您可以在一条语句中选择和更新,该语句应以原子方式执行: UPDATE tbl SET sta

我需要在MySQL/InnoDB上执行以下操作。假设我有一个由3列组成的表(id、计数器、状态)

我需要:

  • 选择状态为0的行
  • 通过设置status=1更新它们,并将计数器增加1
  • 将所选/更新的id返回给客户端
  • 要求:

    • 要更新的行必须与选定的行完全相同,即使在第一次选择之后添加了新行
    • 不允许对一行进行重复更新,即使多个脚本同时在同一数据上运行

    就性能和可伸缩性而言,哪种解决方案是最好的(适用于大型表)?

    您可以在一条语句中选择和更新,该语句应以原子方式执行:

    UPDATE tbl SET status=1, counter=counter+1 WHERE status=0;
    
    我不知道您在步骤3中想要什么,因为涉及多个id。是否希望从SELECT语句中获得id行表?如果是这样,您也许可以使用存储过程,或者使用
    SELECT。。。锁定共享模式

    您可以执行以下操作

    SELECT  id
    FROM    mytable
    WHERE   status = 0
    FOR UPDATE;
    
    然后在软件中建立ID列表,然后执行以下操作

    UPDATE  mytable
    SET     status = 1,
            cnt = cnt + 1
    WHERE   id IN (...)
    

    太简单&要求太多-看起来像HomeWork我想知道哪些ID受更新影响,并将它们发送回用户。当然,它们必须是原子的和一致的。如果你选择更新,为什么要选择隔离级别可序列化呢?@Alexander:为了避免更新可能由
    选择
    更新
    之间的另一个事务插入的记录。我没有想到这一点。谢谢
    UPDATE  mytable
    SET     status = 1,
            cnt = cnt + 1
    WHERE   id IN (...)