且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

mysql-锁定选择查询的行?

更新时间:2023-01-31 14:10:49

本地MySQL锁定不提供此功能.您可以使用一列来执行锁定".

Native MySQL locking doesn't provide this functionality. You could use a column to perform your "locks".

假设每个线程都有一个唯一的ID,则可以创建一个名为thread_owner的列,默认值为0.

Assuming each thread had a unique ID, you could create a column named thread_owner, with default 0.

一个线程会抓住这样的一行:

One thread would grab a row like this:

UPDATE mytable
SET thread_owner = :my_threadID
WHERE thread_owner = 0
LIMIT 1

然后选择这样的行(如果没有要处理的行,则可能不返回):

Then select the row like this (it might return none, if there were no rows to be processed):

SELECT *
FROM mytable
WHERE thread_owner = :my_threadID

然后处理它,最后将其删除.

Then process it, and finally delete it.

此解决方案在MyISAM和InnoDB上均可使用.

This solution would work on both MyISAM and InnoDB.

但是,对于InnoDB,这可能很慢,因为每个UPDATE语句都试图锁定thread_owner = 0的所有行,除非您确定每次都以相同的顺序锁定所有行,否则甚至可能导致僵局.因此,您可以尝试在UPDATE语句中显式锁定整个表:

However, for InnoDB, it might be slow because each UPDATE statement is trying to lock all rows where thread_owner = 0, and unless you're sure you're locking all rows in the same order each time, it could even cause a deadlock. So, you might try explicitly locking the whole table in your UPDATE statement:

LOCK TABLES mytable WRITE;
UPDATE mytable
SET thread_owner = :my_threadID
WHERE thread_owner = 0
LIMIT 1;
UNLOCK TABLES;

这样,MyISAM和InnoDB都将以相同的方式工作.

That way, both MyISAM and InnoDB will work the same way.