Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
Новини 29 серпня 2026

Песимістичне блокування в Laravel Eloquent з методом refreshForUpdate()

Eloquent вже давно має метод refresh() для перезавантаження моделі з бази даних та lockForUpdate() для встановлення блокування рядка як частини запиту. Чого не було раніше - це можливості виконати обидві операції одночасно для екземпляра моделі. Laravel 13.27 додає метод refreshForUpdate(), який був внесений @stevebauman у pull request #61247.

Що робить новий метод

Метод refreshForUpdate() перезавантажує модель за її первинним ключем із застосуванням FOR UPDATE та оновлює екземпляр на місці:

public function refreshForUpdate()
{
    if (! $this->exists) {
        return $this;
    }
    
    return $this->refreshUsingQuery(
        $this->newQueryWithoutScopes()->lockForUpdate()
    );
}

Метод refreshUsingQuery() - це той самий допоміжний метод, що використовується за лаштунками refresh(). Він обмежує запит до ключа моделі, пропускає його через useWritePdo(), щоб репліка для читання не могла обслужити блокування, на яке ви збираєтеся покладатися, викликає firstOrFail(), замінює сирі атрибути, перезавантажує будь-які зв'язки, які вже були завантажені, та синхронізує початковий стан атрибутів. Єдине, що додає refreshForUpdate() - це блокування.

Порівняння підходів

До появи методу refreshForUpdate() безпечне зменшення запасів продукту виглядало б так:

public function purchase(Product $product): Response
{
    DB::transaction(function () use ($product) {
        $product = Product::query()
            ->lockForUpdate()
            ->findOrFail($product->getKey());
            
        if ($product->stock === 0) {
            throw new RuntimeException('The product is out of stock.');
        }
        
        $product->decrement('stock');
    });
    // ...
}

Тепер ви можете перезавантажити та заблокувати модель безпосередньо за допомогою refreshForUpdate():

public function purchase(Product $product): Response
{
    DB::transaction(function () use ($product) {
        $product->refreshForUpdate();
        
        if ($product->stock === 0) {
            throw new RuntimeException('The product is out of stock.');
        }
        
        $product->decrement('stock');
    });
    // ...
}

Переваги нового підходу

Новий метод робить код більш виразним та зрозумілим. Замість того, щоб створювати новий запит, застосовувати блокування та знаходити модель заново, ви просто викликаєте один метод на вже існуючому екземплярі моделі. Це особливо зручно, коли модель вже передана в метод як параметр.

Метод автоматично обробляє всі важливі деталі: використовує з'єднання для запису (а не репліку для читання), перезавантажує всі попередньо завантажені зв'язки та синхронізує стан атрибутів. Це робить песимістичне блокування простішим у використанні та менш схильним до помилок.

Додаткові матеріали

Для глибшого розуміння теми песимістичного блокування та управління гонками даних у Laravel рекомендується ознайомитися з:

  • Повним оглядом Laravel 13.27 та методу refreshForUpdate()
  • Статтею про управління гонками даних за допомогою песимістичного блокування в Laravel
  • Матеріалом про виявлення та виправлення умов гонки в Laravel-додатках
  • Інформацією про запобігання умовам гонки за допомогою атомарних блокувань кешу
5

Читати в документації

Коментарі

Увійдіть, щоб залишити коментар

Будьте першим, хто залишить коментар!

Читайте також

Filament v5.10.0
Новини 12 жовтня 2026

Filament v5.10.0: сітка в rich editor, скелетони таблиць і десятки виправлень

Вийшов Filament v5.10.0: елементи керування сіткою в rich editor, допоміжний контент для віджетів-графіків, скелетони завантаження таблиць, submitOnCompletion() для OneTimeCodeInput та багато виправлень авторизації, доступності й стану.

18
Laravel AI SDK на практиці
Новини 09 жовтня 2026

Laravel AI SDK на практиці: агент, що стоїть за There There

Фрік Ван дер Гертен розповідає, як у Spatie побудували AI-шар хелпдеска There There на Laravel AI SDK: клас агента, інструменти з типізованою JSON-схемою та делегування роботи звичайним domain-діям.

16

Вакансії за темою

Z Global E-Commerce
18 днів тому

Full-Stack Developer (PHP/Laravel + Vue 3)

Full-Stack розробник з глибоким досвідом бекенду. Розробляєте масштабовані веб-платформи з комплексною бізнес-логікою, працюєте з PHP/Laravel, SQL, Vue 3/TypeScript. Основні вимоги: досвід з Laravel, Eloquent, проектування API, оптимізація баз даних (включно з мільйонами записів), фронтенд на Vue 3 з Composition API, TypeScript. Цінується розуміння архітектури, продуктивності й довгострокової підтримуваності коду.

Wooden Sword
19 днів тому

Senior PHP Developer (Game Backend)

Розробник backend для мобільної RPG з високим навантаженням. Основний стек: PHP Laravel API та TypeScript Nakama Game Server. Відповідальність за повний цикл розробки функцій — від логіки до тестування, code review, оптимізації та документації. Вимоги: 5+ років backend-досвіду, бездоганне знання Laravel/PHP, сильні навички TypeScript, PostgreSQL та асинхронного програмування.

Kredyt Kapital
19 днів тому

Middle Full-Stack Developer (PHP / Laravel / Vue / React)

Middle Full-Stack Developer для розробки внутрішніх IT-продуктів. Основний стек: PHP 8.3+, Laravel, PostgreSQL, REST API, Vue.js/React. Розробник займатиметься backend (бізнес-логіка, Eloquent, Jobs/Queues) і frontend (компоненти, інтерфейси), інтеграціями та оптимізацією. Вимоги: 2-3+ років комерційного досвіду з PHP, 2+ років практики з Laravel, впевнене знання PostgreSQL, Git, JavaScript ES6+.

Пакети за темою

Sushi

calebporzio/sushi

Додатковий драйвер для Eloquent, який дозволяє працювати з масивами даних як з повноцінними Eloquent моделями.

3,007 v2.5.4 13 16

Eloquent Has Many Deep

staudenmeir/eloquent-has-many-deep

Laravel Eloquent відносини HasManyThrough з необмеженою кількістю рівнів вкладеності.

2,873 v1.22.1 8