Как осуществить потоконезависимую выборку записи из MySQL?

Здравствуйте.

Есть таблица, в ней 2 поля: id, last_use.

Задача:
для множества клиентов, которые будут делать запросы одновременно, нужно каждый раз выбирать и отдавать id, которому соответствует самый старый last_use и тут же этой записи поставить last_use = NOW().

Пожалуйста, подскажите, как решить эту задачу, чтобы при одновременных запросах не выдавался некоторым клиентам один и тот же id, на который еще не успел сделаться update last_use?
  • Вопрос задан
  • 2643 просмотра
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Три запроса:
SET @id := 0;
UPDATE `table` AS `t1`
    INNER JOIN (SELECT MIN(`last_use`) AS `last_use` FROM `table`) AS `t2` USING(`last_use`)
    SET `t1`.`last_use` = NOW()
    WHERE @id = 0 AND @id := `id`;
SELECT * 
    FROM `table` 
    WHERE `id` = @id;

Первый запрос обнуляет переменную для ограничения изменений одной строкой, LIMIT 1 не подходит для составных запросов.
Второй запрос атомарный, изменение `last_use` и присвоение переменной проходят одновременно, без пересечения с другими запросами.
Переменная @id остаётся в контексте соединения и по ней третьим запросом выбирается строка.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
tyzhnenko
@tyzhnenko
System Administrator, DevOps, QA Engineer
SELECT GET_LOCK('GET_MY_ID', 10);
BEGIN;
SELECT @id_to_update:=`id` FROM `table` ORDER BY `last_use` LIMIT 1;
UPDATE `table` SET `last_use` = NOW() WHERE `id` = @id_to_update;
COMMIT;
SELECT RELASE_LOCK('GET_MY_ID');
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы