0

这是我从未完全掌握的东西,我想知道我是否做得对并检查它的完整性。

……

我有一个数据库links,让我们保持简单,2 列

ID int(10) PK, Status enum('ready', 'in progress', 'complete');
1“准备好”
2'准备好了'
3'准备好了'

……

然后我有一个 API,当查询返回“就绪”项目的 ID 时,这个 API 可以同时调用很多次,我想确保 ID 只给出一次。

……

API MySQL 查询..

锁定表`链接`写
SELECT ID FROM links WHERE status = 'ready' LIMIT 1 // 得到一个准备好的
UPDATE links SET status = 'in progress' WHERE ID = 'X' // 更新刚刚从上面一行获得的链接正在进行中(因此未被另一个 API 调用选择
解锁桌子

因此,如果两个 API 调用相隔 0.01 秒,第一个应该锁定表更新它进行中,解锁后第二个得到它的机会并且做同样的但选择不同的 ID 到第一个得到。

这个对吗?还是做这种事情的最好方法?因为它似乎会导致 MySQL 流量长时间延迟,一些查询等待 5 分钟左右,然后 MySQL 达到最大连接数,这会导致各种其他问题。

该表是 InnoDB,相对较小,大约有 165k 行,带有关于状态的索引,提前感谢您的任何建议或指点。

4

1 回答 1

0

您不需要锁定整个表。
做就是了:

UPDATE links SET status = 'in progress' 
WHERE status = 'Ready'
LIMIT 1;

或者,如果您想检索更新的 id,请使用:

start transaction;
select id into @xx from links
where status = 'Ready'
limit 1 for update;
update links set status = 'in progress'
where id = @xx;
commit;

这些命令将在读取提交的隔离级别和更高级别下工作。
由于“状态”列上有索引,MySql 将在事务期间仅在一个更新的行上放置写锁,而其他行未锁定。

于 2013-08-27T15:37:14.453 回答