2010-07-23 9 views
0

У меня возникла особая проблема с одновременным выполнением AJAX-запросов, которые изменяют объект PHP, хранящийся в сеансе. У меня проблемы с условиями гонки, но я не понимаю, почему они происходят ... только один вызов AJAX может открывать сессию одновременно, поэтому, если они сохраняют сеанс открытым при внесении изменений, не должны позвоните, чтобы увидеть изменения, сделанные другими? Вот упрощенная версия потока (A и B - два набора параметров):Одновременные запросы AJAX и сеансы PHP

1) Выполняется вызов AJAX, который запускает Initiate (A). Этот вызов открывает сеанс. Он обновляет объект PHP, добавляя в массив «A - Running».
2) Выполняется вызов AJAX для запуска (A). Он ждет, пока Initiate (A) не закроет сеанс, а затем запустится. Он кратко открывает сеанс, но явно закрывает его и не изменяет объект. Запуск (A) займет до 60 секунд.
3) Выполняется другой вызов AJAX, который запускает Initiate (B). Это открывает сеанс и изменяет объект, добавляя в массив «B - Running».
4) Еще один вызов AJAX выполняется для запуска (B). Он открывает сессию кратко, но явно закрывает ее.

Пока все отлично. Run (A) и Run (B) выполняются. Оба «A - Running» и «B - Running» находятся в массиве объекта, хранятся в сеансе, который не открыт ни в одном запросе. Вот где вещи становятся забавными:

5) Запуск (A) завершает выполнение сначала, и выполняется вызов AJAX, который запускает Show (A). Это открывает сеанс, извлекает объект и изменяет «A - Бег» на «A - Завершить». Забавно, что «Бег-Б» вообще не существует.
6) Когда Запуск (B) завершается, выполняется вызов AJAX, который выполняет Show (B). Это открывает сеанс и возвращает объект. Он изменяет «B - Бег» на «B - Завершить». Однако первым элементом массива является «A - Running».

Если сеанс закрыт и сохранен, когда Show (A) открывает его, почему он не видит изменения, внесенные Initiate (B)? И когда Initiate (B) может ясно видеть изменения, сделанные Initiate (A), но Show (B) не может видеть, что показывает (A) ...

Аналогичные проблемы возникают, если Run (B) закончен раньше Run (A).

+0

Возможно, вы используете собственный обработчик сеанса, а не по умолчанию, который использует файлы на диске? – Charles

+0

Мы используем внешнюю среду (eyeOS), но я не вижу никаких вызовов session_set_save_handler в любом месте своего кода. Нет другого способа использовать пользовательские обработчики сеансов? Я также вижу a/tmp/sess_ (my session_id) на сервере. – Derek

+0

Скорее всего, вы используете файловую систему сеансов. Казалось, что это был случай пользовательского обработчика сеанса и блокировки базы данных, но теперь я не уверен. – Charles

ответ

1

Похоже, что это связано с каркасом eyeOS. Похоже, так как я начинаю session_write_close() в начале моей функции Run, у меня есть session_start() в конце моей функции Run ... иначе eyeOS не сможет правильно очистить или что-то в этом роде.

Я работаю над этим в течение 3 дней. Мораль истории: не используйте eyeOS для разработки!

Смежные вопросы