PHP Session Locking: почему AJAX-запросы выполняются последовательно кратко

Лекция



Асинхронные запросы позволяют браузеру одновременно обращаться к нескольким API-эндпоинтам, не блокируя интерфейс пользователя. Но на стороне PHP такая параллельность может неожиданно исчезнуть.

Причина — механизм блокировки сессии. Если несколько запросов от одного пользователя используют одну PHP-сессию, каждый из них может ждать освобождения session lock, из-за чего запросы, отправленные одновременно через AJAX или fetch, фактически выполняются последовательно.

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

В этой статье разберем, почему возникает блокировка PHP-сессии, как она влияет на асинхронные запросы и какие есть способы решить проблему — от раннего вызова session_write_close() до полного отказа от session-based authentication в API.

В PHP есть очень характерная проблема с сессиями и параллельными AJAX/fetch-запросами: сессия фактически может превратить асинхронные запросы в последовательные.

В чем проблема

Представим, браузер одновременно отправляет:

 GET /api/user
GET /api/products
GET /api/messages
GET /api/notifications

Ты ожидаешь:

 ┌─ /user ───────┐
├─ /products ───┤
START ─┼─ /messages ───┼─> одновременно
└─ /notifications

Но если каждый PHP-скрипт делает:

 session_start();

то PHP обычно блокирует сессионные данные для данного пользователя. Следующий запрос с тем же PHPSESSID ждет, пока предыдущий запрос закончит работу с сессией.

Получается примерно:

 Request 1: session_start()
└────── работа 1 ──────┘
session закрыта

Request 2: WAIT ──────────┘
└── работа 2 ───

Request 3: WAIT ─────────────────────────┘
└─ работа 3

То есть AJAX технически асинхронный на стороне браузера, но PHP-запросы могут сериализоваться из-за lock сессии. Это особенно заметно, если один запрос долго выполняется.

Например

Допустим, каждый endpoint работает 1 секунду.

Без блокировки:

 4 запроса × 1 секунда
≈ 1 секунда общего времени

При блокировке одной PHP-сессии:

 request 1 → 1 сек
request 2 → 1 сек
request 3 → 1 сек
request 4 → 1 сек
≈ 4 секунды

И это может происходить только для одного пользователя/одной сессии, поэтому на серверных нагрузочных тестах проблема иногда вообще незаметна.

Решение №1 — session_write_close()

Если сессия нужна только в начале запроса, например:

 session_start();
$userId = $_SESSION['user_id'];

а дальше выполняется тяжелая работа:

 // запросы к БД
// API
// обработка
// вычисления
// sleep()
// и т.д.

то лучше:

 session_start();
$userId = $_SESSION['user_id'];
session_write_close();
// дальше долгая работа

session_write_close() сохраняет данные сессии и освобождает блокировку, после чего другие параллельные запросы этого пользователя могут продолжить работу.

Важный нюанс

После:

 session_write_close();

ты не должен рассчитывать, что изменения в $_SESSION дальше будут сохранены.

Например:

 session_start();
$_SESSION['user_id'] = 123;
session_write_close();
$_SESSION['something'] = 'abc'; // это уже не будет нормально сохранено

Поэтому правильная схема:

 session_start();
$userId = $_SESSION['user_id'];
$someValue = $_SESSION['someValue'];
session_write_close();
// вся остальная работа

Особенно актуально для Laravel

Если ты имеешь в виду именно Laravel, то проблема тоже актуальна.

Например, у тебя React делает одновременно:

 /api/services
/api/products
/api/messages
/api/profile
/api/notifications

и Laravel использует обычную session-based authentication.

Если middleware открывает сессию, а endpoint затем выполняет долгую операцию, другие запросы этого же пользователя могут ждать освобождения session lock.

Поэтому иногда возникает очень странная ситуация:

«У меня 5 AJAX-запросов отправляются одновременно, но почему сервер обрабатывает их один за другим?»

И первая вещь, которую стоит проверить — PHP session locking.

Это не проблема самих async/await, React, Axios или браузера. Это серверная синхронизация доступа к сессии.

Если первое решение — session_write_close(), то второе принципиальное решение — вообще не использовать PHP-сессии для API-запросов, а перейти на stateless-аутентификацию, например Bearer-токены.

2. Убрать session-based authentication из API

Вместо:

 Browse
│
│ PHPSESSID cookie
▼
PHP Session
│
└── session lock

использовать:

 Browser
│
│ Authorization: Bearer 
▼
API
│
└── проверка токена

Тогда каждый запрос не открывает общую PHP-сессию пользователя и не блокирует другие параллельные запросы.

Например:

 GET /api/messages
Authorization: Bearer abc123

одновременно:

 GET /api/services
Authorization: Bearer abc123

и:

 GET /api/profile
Authorization: Bearer abc123

Все три запроса могут независимо выполняться на сервере.

Для Laravel

Для API обычно используют:

  • Laravel Sanctum — хороший вариант для SPA/API;
  • Passport — если нужен полноценный OAuth2;
  • собственные Bearer tokens — возможно, но обычно нет смысла изобретать свою систему.

У тебя, судя по предыдущим вопросам, уже был вариант с Bearer token в localStorage и Axios interceptor. В таком случае это как раз подход, который позволяет не зависеть от PHP session lock.

Но есть важный момент

Не стоит думать:

«Bearer token автоматически делает запросы быстрыми».

Он только убирает проблему блокировки PHP-сессии. Если все 5 запросов одновременно обращаются к одной медленной БД или выполняют тяжелую операцию, они все равно могут тормозить.

Итого:

Подход Session lock Параллельные API-запросы
PHP Session + session_start() Да +- могут блокироваться
Session + session_write_close() Только короткое время +
Bearer Token / stateless API Нет +
Laravel Sanctum API Зависит от способа аутентификации +при token-based API

Если API у тебя преимущественно REST + React, я бы предпочел второй подход: stateless API с Bearer token.

Заключение

PHP-сессии удобны, но их механизм блокировки важно учитывать при разработке приложений с большим количеством параллельных запросов.

Если несколько AJAX-запросов используют одну сессию, долгий запрос может удерживать session lock и заставлять остальные запросы ждать. Внешне это выглядит так, будто асинхронные запросы выполняются последовательно, хотя браузер отправил их одновременно.

Если сессия нужна только для чтения данных в начале запроса, простое решение — получить необходимые значения и как можно раньше вызвать session_write_close(). Это освобождает блокировку и позволяет другим запросам продолжить выполнение.

Для API, особенно в SPA и мобильных приложениях, еще лучше рассмотреть stateless-аутентификацию с Bearer-токенами. В таком подходе состояние пользователя не хранится в общей PHP-сессии, поэтому запросы не конкурируют за один session lock.

Главный принцип простой: не удерживайте PHP-сессию дольше, чем это действительно необходимо. Асинхронность на стороне клиента имеет смысл только тогда, когда сервер также способен обрабатывать запросы параллельно.

создано: 2026-08-22
обновлено: 2026-08-22
1



Помог ли вам этот ответ?
Нажмите оценку и напишите коротко почему. Так мы сможем сделать следующие ответы точнее и полезнее.
Насколько вы довольны ответом?
Ваш отзыв напрямую влияет на качество следующих подсказок и ответов.


Поделиться:
Пожаловаться

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выполнения задания
  • Возможно применение функции гаранта на сделку
  • Приоритетная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можете продать (как исполнитель) или купить (как заказчик) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно применение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей

Комментарии

Оставить комментарий

Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Лекции и учебник по "Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend) "

Термины: Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)