Новое в журнале. Laravel 13.38 лечит чтение с устаревшей реплики
PHP и бэкенд

Laravel 13.38 лечит чтение с устаревшей реплики

20 октября 2026 года вышел Laravel 13.38 с middleware PreventStaleDatabaseReads и методом usingWritePdo(): классическая проблема read-реплик — «я только что сохранил форму, а на следующей странице вижу старые данные» — теперь решается без кастомных обёрток в каждом контроллере.

22 октября 20265 мин чтенияНовости
Laravel 13.38 лечит чтение с устаревшей реплики
13.38.0версия Laravel с релизом, 20 октября 2026
2 секокно «своего чтения» по умолчанию после записи

20 октября 2026 года в релизе laravel/framework 13.38.0 появилось два связанных изменения для приложений, которые читают данные с реплик базы: middleware PreventStaleDatabaseReads и метод DB::usingWritePdo(). Разбор механики с примерами кода опубликовал Laravel News — независимое издание, которое много лет курирует релизы фреймворка и регулярно сверяется с официальными changelog и PR-ами мейнтейнеров.

Что вышло

PreventStaleDatabaseReads — это middleware, которое после любой записи сохраняет в сессии пользователя метку времени. В течение короткого окна (по умолчанию 2 секунды, настраивается) последующие чтения этого же пользователя идут не через read-реплику, а через write-соединение — то, которое только что приняло запись. Как только окно истекает, чтения снова уходят на реплики. usingWritePdo() решает ту же задачу точечно: внутри callback все запросы принудительно идут через write-соединение, без привязки к сессии и глобальному middleware — удобно для одного проблемного участка кода, а не всего приложения.

В чём проблема реплик

Схема master-реплика — стандартный способ горизонтально масштабировать чтение: один write-узел принимает все изменения, несколько read-реплик обслуживают запросы на чтение и синхронизируются с задержкой в десятки-сотни миллисекунд. Для большинства сценариев это незаметно. Но ровно после записи — пользователь сохранил профиль, оформил заказ, отправил комментарий — следующий же GET-запрос рискует попасть на реплику, которая ещё не получила свежую строку. Результат пользователь видит как баг: «я же только что это сохранил, а оно пропало». До 13.38 эту проблему в Laravel закрывали руками — либо временным переключением на write-соединение в конкретном контроллере, либо принудительным redirect с задержкой, либо вовсе игнорированием, пока на это не пожалуются достаточно громко.

Кому это реально нужно

Если проект работает с одной базой без реплик, изменение ничего не меняет — PreventStaleDatabaseReads актуален только там, где read/write уже разделены. Но появление встроенного решения в ядре фреймворка — само по себе сигнал: раз Laravel включает такой middleware в стандартную поставку, значит разделение чтения и записи стало достаточно частым сценарием даже для проектов среднего размера, а не только для систем с миллионами пользователей. Архитектурное решение «когда пора заводить реплики и как не словить на этом баги консистентности» — ровно то место, где самодеятельность дороже всего обходится: поставить реплику легко, а не затопить приложение гонками чтения-записи — отдельная инженерная задача.

Что делать команде

  • Если у проекта уже есть read-реплики — обновиться до 13.38 и заменить самодельные обходы стандартным middleware, это меньше кода для поддержки
  • Если реплик пока нет, но трафик на чтение растёт — держать это изменение в уме как готовый кусок архитектуры на момент, когда разделение понадобится
  • Проверить таймаут по умолчанию (2 секунды) на своих сценариях: для операций с более долгой асинхронной обработкой перед записью в базу его может не хватить

Когда дело доходит до реального разделения чтения и записи в продакшене, вопросов обычно больше, чем просто включить middleware — нужно продумать схему репликации, мониторинг лага, поведение при отказе одной из реплик и миграции без простоя. Для команд без выделенного архитектора под рукой разумнее не экспериментировать на проде, а привлечь подрядчика, который уже проектировал такие схемы: команда YUSMP Group ведёт разработку под ключ, включая архитектуру баз данных и масштабирование на этапе роста нагрузки.

Код, который не стыдно передать

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

Случайный разбор