Блокировка посетителя, пока MySQL запрос не будет завершен - PullRequest
0 голосов
/ 26 сентября 2010

У меня есть несколько страниц на сайте, для которых действия, которые могут быть выполнены на одной странице, зависят от информации в базе данных для посетителя сайта.Итак, допустим, посетитель A заходит на страницу B и обновляет базу данных, чтобы показать, что он присоединился к определенной группе.Затем посетитель переходит на страницу C, страницу группы.Если пользователь является членом группы, ему показывается содержимое участника.Если это не так, им показывается контент, не принадлежащий участнику.Здесь возникает проблема (кстати, страницы в php):

В идеальном мире выполнение запроса на странице B будет выполнено мгновенно, прежде чем пользователь перейдет на страницу C, поэтому база данных всегда заполнена наибольшим количествомсвежая информация о государствах-членах.Однако может случиться так, что сервер находится под большой нагрузкой, и запрос не завершается к тому времени, когда пользователь переходит на страницу C. Таким образом, даже если пользователь является членом группы, это не отражается на странице Cпоскольку запрос еще не завершен.

Есть ли способ сделать так, чтобы, если пользователь запускает запрос на странице, до тех пор, пока этот запрос не завершит любую другую страницу, которую он пытается посетить, просто "зависнет" изагрузка после завершения запроса или до истечения заданного количества времени?Я могу сделать эту систему вручную, но если у mysql и php уже есть что-то встроенное, это было бы предпочтительным.

В случае, если это имеет значение, я использую сервер LAMP.

Ответы [ 3 ]

1 голос
/ 26 сентября 2010

Если вы не сделаете что-нибудь причудливое, например, реплицированные серверы баз данных или системы очередей сообщений, то на самом деле уже работает один сервер MySQL и PHP.Введите UPDATE или INSERT на странице B, и запрос не вернется, пока он не будет зафиксирован.Поэтому не возвращайте HTML-код со страницы B, пока не выполните запрос, что вам в любом случае не понадобится, так как сначала нужно убедиться, что ошибки не было.Тогда страница C будет в порядке.

0 голосов
/ 26 сентября 2010

Может ли посетитель просто не показывать ссылку на страницу C, пока подтверждение не произойдет на странице B? Таким образом, они присоединяются к группе на странице B, что происходит путем отправки сообщения формы на отдельную промежуточную страницу обработчика форм F, а затем, когда это делается (т. Е. Вставка mysql завершена успешно), она снова загружает страницу B с соответствующей новой информацией и указаниями для страница С.

Если ссылки на странице C должны появляться всегда или пользователь может добавить их в закладки, то, возможно, на странице C также может отображаться дата записи, предлагая пользователю кнопку «Обновить», если его запись не соответствует он просто попросил его немного подождать и повторить попытку.

В любом случае, в mysql вы говорите о концепции или блокировке строк, но пытаетесь применить это к сайту с несколькими входами. Я не знаю ни одного такого встроенного механизма в PHP, но вы можете подделать его с семафорами для пользователя, если хотите:

  • пользователь инициирует действие
  • PHP устанавливает блокировку для этого пользователя либо путем создания уникального файла, либо путем установки уникального ключа в хранилище памяти, таком как memcache, или в пользовательском сеансе
  • эта блокировка означает, что действие еще не завершено
  • PHP выполняет действие (вставка mysql, что угодно)
  • когда действие завершено и проверено, снимите блокировку

Затем вы можете использовать наличие блокировки, чтобы определить, должна ли загружаться страница C и отображать что-то описательное для пользователя, например, мое предложение «Обновить», приведенное выше.

0 голосов
/ 26 сентября 2010

Предполагая, что у вас есть строка, которая однозначно идентифицирует текущего пользователя, скажем 'identifyuser', выберите разумное время ожидания и выполните SELECT GET_LOCK('identifyuser',timeout) перед любой другой активностью базы данных для данного запроса и SELECT RELEASE_LOCK('identifyuser') после всей активности базы данных для запроса.

...