Недостатки блокировки строк MySQL
Я использую блокировку строк (транзакции) в MySQL для создания очереди заданий. Используемый движок - InnoDB.
SQL-запрос
START TRANSACTION;
SELECT *
FROM mytable
WHERE status IS NULL
ORDER BY timestamp DESC LIMIT 1
FOR UPDATE;
UPDATE mytable SET status = 1;
COMMIT;
The problem with SELECT FOR UPDATE is that it usually creates a single synchronization point for all of the worker processes, and you see a lot of processes waiting for the locks to be released with COMMIT.
Вопрос: Означает ли это, что при выполнении первого запроса, для завершения транзакции которого требуется некоторое время, когда второй аналогичный запрос выполняется до фиксации первой транзакции, ему придется подождать, пока он завершится, прежде чем запрос выполнен? Если это так, то я не понимаю, почему блокировка строки одной строки (что я предполагаю) повлияет на следующий запрос транзакции, который не потребует чтения этой заблокированной строки?
Кроме того, можно ли решить эту проблему (и при этом добиться эффекта блокировки строк для очереди заданий), выполнив UPDATE
вместо транзакции?
UPDATE mytable SET status = 1
WHERE status IS NULL
ORDER BY timestamp DESC
LIMIT 1
1 answers
Если вы используете FOR UPDATE
с механизмом хранения, который использует блокировки страниц или строк, строки, проверенные запросом, блокируются на запись до конца текущей транзакции. Использование LOCK IN SHARE MODE
устанавливает общую блокировку, которая позволяет другим транзакциям считывать проверенные строки, но не update or delete
их.
и об этом запросе
UPDATE mytable SET status = 1
WHERE status IS NULL
ORDER BY timestamp DESC
LIMIT 1
Начиная с innodb
Автоматическое получение блокировок во время обработки инструкций SQL, я думаю, что это работает так же.