Кажется, вы определенно находитесь на правильной стойке с блокировкой сеанса PHP:
Примечания о блокировке сеанса (параллелизм)
Модель сеанса PHP по умолчанию блокирует сеанс до завершения загрузки страницы.Таким образом, если у вас есть два или три кадра, которые загружаются, и каждый использует сеансы, они будут загружаться по одному за раз.Это связано с тем, что только один контекст выполнения PHP имеет право на запись в сеанс одновременно.
Некоторые люди обходят это, вызывая session_write_close()
, как только они закончили записывать любые данные в $_SESSION
- они могут продолжать читать данные даже после того, как они их вызвали. Недостаток session_write_close()
заключается в том, что ваш код все еще будет блокироваться при первом вызове session_start()
на любой странице сеанса, и что вам придется посыпать session_write_close()
везде, где вы используете сеансы, как толькокак вы можете.Это все еще очень хороший метод, но если ваш доступ к сеансу следует определенным шаблонам, у вас может быть другой способ, который требует меньше изменений вашего кода.
Идея состоит в том, что если ваш код сеанса в основном читает сессий и редко пишет в них, тогда вы можете разрешить параллельный доступ.Чтобы предотвратить полностью испорченные данные сеанса, мы заблокируем хранилище резервных копий сеанса (обычно это файлы tmp) во время записи в них.Это означает, что сеанс заблокирован только на короткое время, которое мы записываем в резервное хранилище.Однако это означает, что если две страницы загружаются одновременно и обе изменяют сеанс, Last One Wins .В зависимости от того, кто загружает первым, его данные перезаписываются данными, загружаемыми вторыми.Если с вами все в порядке, вы можете продолжить, в противном случае используйте метод session_write_close, описанный выше.
Если у вас есть сложные фрагменты кода, которые зависят от какого-либо состояния в сеансе и некоторого состояния в базе данных или текстефайл или что-то еще - опять же, вы можете не захотеть использовать этот метод.Когда у вас одновременно запущены две страницы, вы можете обнаружить, что одна страница проходит на полпути, изменяя ваш текстовый файл, затем вторая проходит весь путь, далее изменяя ваш текстовый файл, затем первая завершается - и ваши данные могут бытьискажены или полностью потеряны.
Так что, если вы готовы к отладке потенциально очень, очень неприятных условий гонки, и ваши шаблоны доступа для ваших сессий чаще всего читаются и редко пишутся (и не пишутся дорого), затем вы можете попробовать следующую систему.
Скопируйте пример из session_set_save_handler () в ваш включаемый файл выше, где вы начинаете свои сеансы.Измените метод write () для сеанса:
function write($id, $sess_data)
{
global $sess_save_path, $sess_session_name;
$sess_file = "$sess_save_path/sess_$id";
if ($fp = @fopen($sess_file, "w")) {
flock($fp,LOCK_EX);
$results=fwrite($fp, $sess_data);
flock($fp,LOCK_UN);
return($results);
} else {
return(false);
}
}
Возможно, вы также захотите добавить метод GC (Сборка мусора) для сеансов.
И, конечно, возьмите этосовет с небольшим количеством соли - в настоящее время он работает на нашем тестовом сервере, и, похоже, он работает нормально, но люди сообщают об ужасных проблемах с обработчиком сеансов общей памяти, и этот метод может быть столь же небезопасным, как этот.
Вы также можете рассмотреть возможность реализации собственных блокировок для страшных битов кода, чувствительных к параллелизму.
Ref: http://ch2.php.net/manual/en/ref.session.php#64525
Возможно, стоит реализовать сеанс базы данныхобработчик.Использование базы данных устраняет эту проблему и может немного улучшить производительность, если используется хорошая структура базы данных.