Параллельное получение задач из таблицы MySQL

У меня много консольных приложений, которые выполняют разные задачи. Я получил уникальное задание из php скрипта:

$mysqli->autocommit(FALSE);
$result = $mysqli->query("SELECT id, task FROM queue WHERE locked = 0 LIMIT 1 FOR UPDATE;");

while($row = $result->fetch_assoc()){
$mysqli->query('UPDATE queue SET locked = 1 WHERE id="'.$row['id'].'";');
$mysqli->commit();
$response["response"]["task"] = $row["task"];
}

$mysqli->close();
echo json_encode($response);

Иногда у меня есть дублирующееся задание: «При попытке получить блокировку обнаружен тупик; попробуйте перезапустить транзакцию».
Что я делаю неправильно?

UPD: установить индекс для «заблокированного» столбца решить проблему

1

Решение

Из документации MySQL Как минимизировать и справиться с тупиками:

Добавьте правильно выбранные индексы в ваши таблицы. Тогда ваши запросы должны сканировать меньше записей индекса и, следовательно, устанавливать меньше блокировок.

Добавление индекса к locked колонка должна решить это. Без этого SELECT запрос должен сканировать таблицу, ища строку с locked = 0и все строки, через которые он проходит, должны быть заблокированы.

Если вы добавите индекс к столбцу в WHERE оговорка, он может перейти непосредственно к этой записи и заблокировать ее. Другие записи не заблокированы, поэтому вероятность взаимоблокировки снижена.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]