Select 并在不发生冲突的情况下更新 MySQL 中的几行

Select and update a couple of rows in MySQL without collision

请考虑有一个充满记录的存储库 table。将有许多并发请求从存储 table.

中挑选和拥有一些记录

我不确定,也不知道如何在没有任何联盟的情况下使用 Transcations 组合 select 和更新来执行我所说的。

例如,这是我的 table:

+----+------+----------+
| id | name | is_taken |
+----+------+----------+
|  1 | a    |        1 |
|  2 | b    |        0 |
|  3 | c    |        0 |
|  4 | aa   |        1 |
|  5 | bb   |        0 |
|  6 | dd   |        0 |
|  7 | e    |        0 |
|  8 | ff   |        0 |
+----+------+----------+

--

-- first select them
SELECT * FROM `STASH` WHERE `is_taken` = 0 LIMIT 2
-- then update and take them to stop others to taking them
UPDATE `STASH` SET `is_taken` = 1 WHERE `is_taken` = 0

您可能需要考虑向 table 添加所有者列(如果还没有)。然后只需 运行 更新语句,设置所有者并获取该行。每个逻辑事务都应该有唯一的所有者。

update stash set owner = some_owner, is_taken = 1 where is_taken = 0 limit 2;

应在您预期的并发负载下测试此语句以查看其执行情况。

然后select那些行

select * from stash where owner = some_owner and is_taken = 1;

然后在发布的时候,使用上面的ids select

update stash set owner = null, is_taken = 0 where id in (...);

如果您使用 table 作为操作队列并且它们很短:

START TRANSACTION;
SELECT ... FOR UPDATE;
act on them
DELETE ...; -- assuming you are finished with them.
COMMIT;

并在每个阶段检查错误。如果遇到死锁或锁定等待超时,请重新启动。

如果操作需要很长时间,则应使用不同的技术。

所以,请详细说明

  • table
  • 中通常(和最大值)有多少行
  • 您希望一次选择多少行
  • 'process'一行需要多长时间
  • 完成后是否可以删除该行。

不同的技术效果更好,具体取决于您的回答。