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'一行需要多长时间
- 完成后是否可以删除该行。
不同的技术效果更好,具体取决于您的回答。
请考虑有一个充满记录的存储库 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'一行需要多长时间
- 完成后是否可以删除该行。
不同的技术效果更好,具体取决于您的回答。