Может ли кеширование данных вызывать помехи? - PullRequest
1 голос
/ 06 февраля 2011

Я пишу новый движок для моих сайтов PHP, который имеет функцию кэширования данных.Теперь мне интересно, возможно ли вмешательство между этими сценариями.Рассмотрим следующий пример:

Допустим, многие пользователи посещают веб-сайт, связанный с фотографией, и два из них запускают два сценария практически в одно и то же время.

Скрипт 1 удаляет пользователя с именем 'FooBar' и все его фотографии из базы данных.

Скрипт 2 отображает фотографию № 12345 (сделанную FooBar).

  1. (Скрипт 1) проверяет, существует ли пользователь 'FooBar'.Сохраните его идентификатор в переменной $id.
  2. (сценарий 2), чтобы проверить, существует ли фотография с номером 12345.Хранить идентификатор владельца внутри переменной $owner.
  3. (сценарий 1) query("DELETE FROM users WHERE id='$id' ");
  4. (сценарий 2) query("SELECT name FROM users WHERE id='$owner' "); // ошибка здесь
  5. (сценарий 1) query("DELETE FROM photos WHERE owner='$id' ");

Как мы видим, сценарий 2 обнаруживает, что фотография существует, но ее владелец уже удален.

Вопрос : обрабатываются ли сценарии PHP по порядку (поэтому представленный сценарий был бы невозможен)?Если нет, что я могу сделать, чтобы предотвратить такие ошибки при отправке нескольких запросов в одном скрипте?

Большое вам спасибо.


Спасибо за ваши ответы.Представленный сценарий является лишь примером, и я знаю, что это можно сделать лучше.Поэтому при создании большого веб-сайта я должен постоянно знать, что данные могут быть изменены во время выполнения.

Но в этом случае я просто не могу доверять любой информации, хранящейся в переменной в php.Как вы справляетесь с такими проблемами?Обновление или выборка всех данных в одном запросе?

Ответы [ 2 ]

1 голос
/ 06 февраля 2011

Действительно, условия гонки возможны.

Я скажу, что мне кажется странным в сценарии удаления удалить пользователя перед его фотографиями.Если что-то вылетает после удаления пользователя, но до удаления фотографии, то в БД все еще остаются его осиротевшие фотографии.Как правило, транзакции (с использованием механизма хранения, который их поддерживает, например, InnoDB) смягчают эту проблему.

Что касается самого состояния гонки, я полагаю, что существуют методы, использующие блокировку строк для предотвращения одновременного доступа к ним других процессов.

[Если мне удастся провести какое-то исследование, я укажу больше деталей.Мое краткое исследование до сих пор о 'mysql row row' показывает, что некоторые движки фактически неявно блокируют любые строки, на которые влияет транзакция.Но я признаюсь, что не имел прямого опыта там.]

1 голос
/ 06 февраля 2011

Представленный сценарий возможен. Единственное, что я мог бы сказать, что вы можете сделать, это написать ошибку для этой возможности: как вы видите, запрос 4 не возвращает действительного владельца. Теперь вы можете сделать несколько вещей, из которых это только примеры:

  • возвращает имя владельца в комбинированном запросе, чтобы вы могли хотя бы показать имя, если нашли владельца изображения (в пункте 2.). Если позже вы захотите показать больше, вам просто нужно будет вернуть, что владелец не существует (больше). Вот что произошло (он был удален между нагрузками), поэтому, даже если это немного странно для пользователя, ему придется с этим справиться:)
  • Просто покажите ошибку в точке 4, немного похоже на вторую часть предыдущего примера. Вы получили результат очень скоро, но затем он исчез. Таким образом, вы возвращаете «не удалось загрузить пользователя» или что-то в этом роде.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...