Я использую блокировку строк (транзакции) в 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
status IS NULL ORDER BY
запрос гарантирует, что полное сканирование таблицыmytable.
индексов не поможет при поиске IS NULL. Если бы вы могли реорганизовать свой код, чтобы исключить значения состояния NULL, найти какое-то другое значение и использовать для этого индекс, вы бы сэкономили много времени на сканировании таблицы. - person O. Jones   schedule 26.09.2012status
на0
и индексировать его? - person Nyxynyx   schedule 26.09.2012