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

Як атомарні блокування кешу захищають від одночасного виконання?

Cache::lock() дає розподілене блокування: лише один процес на всіх серверах виконує ділянку коду одночасно.

$lock = Cache::lock("invoice:{$order->id}:generate", 30);

if ($lock->get()) {
    try {
        $order->generateInvoice();
    } finally {
        $lock->release();
    }
}

Або коротше - з очікуванням до 5 секунд:

Cache::lock("invoice:{$order->id}:generate", 30)->block(5, function () use ($order) {
    $order->generateInvoice();
});

Де це потрібно:

  • подвійний клік чи повторний вебхук не має створити два рахунки;
  • запланована команда, що запускається на кількох серверах;
  • перерахунок дорогого кешу - лише один процес рахує, інші чекають.

Важливі деталі:

  • Час життя блокування (30 с) - страховка, якщо процес упав і не звільнив його. Якщо робота може тривати довше, блокування закінчиться посередині, і зайде другий процес. Його подовжують через refresh().
  • Власник: release() звільняє лише своє блокування. Щоб звільнити з іншого процесу (наприклад, у завданні черги), передають токен через owner() і restoreLock().
  • Драйвер: потрібен спільний для всіх серверів - Redis, Memcached, database, DynamoDB. file блокує лише в межах одного сервера.

Блокування не замінює унікальних індексів у базі: індекс - остання лінія захисту, блокування лише зменшує кількість конфліктів.

Докладніше в документації: Атомарні блокування

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання