Есть ли способ для MySQL ждать строк, соответствующих условию, которое будет вставлено
предположим, я писал приложение, где мне нужно было бы получать уведомления в режиме реального времени с сервера, и предположим, что эти уведомления хранятся в базе данных mysql. Для меня, чтобы получить их, я должен был бы продолжать опрос сервера mysql (продолжайте повторять тот же выбор запрос, пока я не получу результаты), но я считаю, что это очень неэффективный способ сделать это, так как большую часть времени выбор будет пустым . Если я делаю это часто, это необоснованное напряжение на сервере, если я делаю это редко уведомления приходили очень поздно. Поэтому мне было интересно, есть ли способ заблокировать запрос mysql, пока результат, соответствующий условию, не станет доступным.
list = query ("SELECT * FROM `notifications` WHERE `unread`=1") ;
вместо того, чтобы возвращать пустой список, если нет непрочитанных уведомлений, он будет ждать, пока на самом деле не появятся непрочитанные уведомления для возврата
1 ответов
я рекомендую использовать производителями и потребителями шаблон, реализованный с новой таблицей в качестве "рабочей очереди". Нет необходимости в хранимой процедуре, потому что триггер настолько прост.
- триггер заполнит рабочую очередь
- код опросит таблицу рабочих очередей. Поскольку таблица будет очень маленькой, запрос будет быстрым и малонагруженным.
- код будет делать все, что вам нужно, и удалять строки из таблицы по завершении - держать его как можно меньше
создайте таблицу с идентификатором notification
обрабатывается и столбец "статус обработки", например:
create table work_queue (
id int not null auto_increment,
notification_id int references notifications,
status enum ('ready', 'processing', 'failed')
);
создайте простой триггер, который заполняет таблицу рабочей очереди:
delimiter $
create trigger producer after insert on notifications
for each row begin
insert into work_queue (notification_id, status)
select new.id, 'ready'
where new.unread;
end; $
delimiter ;
ваш код будет иметь псевдо код:
select * from work_queue where status = 'ready' order by id limit 1
update work_queue set status = 'processing' where id = <row.id>
- делать то, что вам нужно
notifications where id = <row.notification_id>
- или
delete from work_queue where id = <row.id>
илиupdate work_queue set status = 'failed' where id = <row.id>
(вам придется выясните, что делать с неудачными элементами) - Sleep 1 секунда (эта пауза должна быть примерно такой же, как пиковая скорость прибытия уведомлений - вам нужно настроить это, чтобы сбалансировать размер work_queue и нагрузку на сервер)
- goto 1.
если у вас есть один опрос процесса, нет необходимости в блокировке беспокойства. Если у вас есть несколько процессов опроса, вам нужно будет обработать условия гонки.