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

Чому слухач у черзі іноді не бачить даних, які щойно створила подія?

Бо подію диспетчеризували всередині транзакції, а воркер узяв завдання раніше, ніж транзакція закомітилася.

DB::transaction(function () use ($data) {
    $order = Order::create($data);
    OrderPlaced::dispatch($order);    // слухач у черзі вже може стартувати
    $order->items()->createMany($data['items']);
});

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

Рішення:

  • ShouldQueueAfterCommit у слухачі - стати в чергу лише після коміту;
  • ShouldDispatchAfterCommit у події - диспетчеризувати саму подію після коміту (не дістануть і синхронні слухачі);
  • after_commit => true у конфігурації підключення черги - для всіх завдань;
  • для спостерігачів - ShouldHandleEventsAfterCommit.

Якщо транзакції немає, усе це спрацьовує одразу, тож поведінка поза транзакцією не змінюється.

Те саме стосується листів і сповіщень у черзі - у них є afterCommit().

Докладніше в документації: Слухачі в черзі й транзакції

Перевір себе

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

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