Я пытаюсь сделать очередь с использованием MySQL (я знаю, стыдно за меня!). Способ, которым я настроен, – это обновление, чтобы установить идентификатор получателя в элементе очереди, после того, как произойдет обновление, я выбираю обновленный элемент идентификатором получателя.
Проблема, с которой я столкнулся, – это когда я запрашиваю обновление, а затем делаю выбор, запрос select возвращает true вместо набора результатов. Это происходит, когда делаются быстрые запросы.
Кто-нибудь знает, почему это происходит?
Заранее спасибо.
Схема:
CREATE TABLE `Queue` ( `id` char(11) NOT NULL DEFAULT '', `status` varchar(20) NOT NULL DEFAULT '', `createdAt` datetime DEFAULT NULL, `receiverId` char(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Dequeue:
update `'.self::getTableName().'` set `status` = 'queued', `receiverId` = '%s' where `status` = 'queued' and `receiverId` is null order by id limit 1; select * from `'.self::getTableName().'` where `receiverId` = \'%s\' order by id desc limit 1
Это звучит как какое-то гоночное состояние. Вы используете MyISAM, поэтому возможно, что обновление может быть отложено (особенно, если в этой таблице много трафика).
true
возврат указывает, что ваш запрос select
выполнен правильно, но возвращен и пустой набор результатов (без строк). Если ваша логика, когда это произойдет, – это подождать, скажем, 50 миллисекунд, и повторите попытку, вы можете обнаружить, что все работает правильно.
Изменить : вы можете попытаться заблокировать таблицу до того, как вы сделаете UPDATE, пока не сделаете последний SELECT. Но это может испортить производительность других частей вашего приложения. Лучше всего сделать так, чтобы ваше приложение было устойчивым в условиях гонки.