РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
1368 of 1392 menu

Класс ShouldDispatchAfterCommit

Класс ShouldDispatchAfterCommit представляет собой интерфейс, который реализуется классами задач для отложенной диспетчеризации. Когда задача реализует этот интерфейс, она не будет отправлена в очередь до тех пор, пока текущая транзакция базы данных не будет успешно завершена. Если транзакция откатывается, задача не будет отправлена. Это полезно для предотвращения выполнения задач, которые зависят от данных, созданных в текущей транзакции.

Синтаксис

Для использования интерфейса нужно реализовать его в классе задачи:

<?php namespace AppJobs; use IlluminateContractsQueueShouldQueue; use IlluminateContractsQueueShouldDispatchAfterCommit; class ExampleJob implements ShouldQueue, ShouldDispatchAfterCommit { // Конструктор и метод handle } ?>

Пример

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

<?php namespace AppJobs; use AppModelsUser; use IlluminateContractsQueueShouldQueue; use IlluminateContractsQueueShouldDispatchAfterCommit; class SendWelcomeEmail implements ShouldQueue, ShouldDispatchAfterCommit { protected $user; public function __construct(User $user) { $this->user = $user; } public function handle() { // Отправка приветственного письма Mail::to($this->user->email)->send(new WelcomeMail($this->user)); } } ?>

Теперь диспетчеризуем эту задачу внутри транзакции:

<?php namespace AppHttpControllers; use AppJobsSendWelcomeEmail; use AppModelsUser; use IlluminateSupportFacadesDB; class UserController extends Controller { public function store(Request $request) { DB::transaction(function () use ($request) { $user = User::create([ 'name' => $request->name, 'email' => $request->email, ]); SendWelcomeEmail::dispatch($user); }); // Задача будет отправлена только после успешного завершения транзакции return redirect()->route('users.index'); } } ?>

Пример

Рассмотрим ситуацию, когда транзакция откатывается из-за ошибки:

<?php namespace AppHttpControllers; use AppJobsProcessOrder; use AppModelsOrder; use IlluminateSupportFacadesDB; use Exception; class OrderController extends Controller { public function create() { try { DB::transaction(function () { $order = Order::create([ 'user_id' => 1, 'amount' => 100, ]); ProcessOrder::dispatch($order); // Имитация ошибки throw new Exception('Ошибка создания заказа'); }); } catch (Exception $e) { // Задача не будет отправлена, так как транзакция откатилась return response()->json(['error' => $e->getMessage()], 500); } } } ?>

Пример

Если задача не реализует интерфейс ShouldDispatchAfterCommit, то она будет отправлена в очередь немедленно, даже внутри транзакции:

<?php namespace AppJobs; use IlluminateContractsQueueShouldQueue; class SendNotification implements ShouldQueue { protected $message; public function __construct($message) { $this->message = $message; } public function handle() { // Отправка уведомления } } ?>

В этом случае задача будет отправлена в очередь сразу, даже если транзакция позже откатится:

<?php namespace AppHttpControllers; use AppJobsSendNotification; use IlluminateSupportFacadesDB; use Exception; class NotificationController extends Controller { public function send() { DB::transaction(function () { SendNotification::dispatch('Тестовое сообщение'); // Имитация ошибки throw new Exception('Ошибка отправки'); }); // Задача уже отправлена, несмотря на откат транзакции } } ?>

Пример

Можно использовать метод afterCommit на экземпляре PendingDispatch для динамической установки поведения:

<?php namespace AppHttpControllers; use AppJobsUpdateProductCache; use AppModelsProduct; use IlluminateSupportFacadesDB; class ProductController extends Controller { public function update(Request $request, $id) { DB::transaction(function () use ($request, $id) { $product = Product::find($id); $product->update([ 'price' => $request->price, 'stock' => $request->stock, ]); UpdateProductCache::dispatch($product)->afterCommit(); }); // Задача будет отправлена после коммита транзакции return redirect()->route('products.show', $id); } } ?>

Результат выполнения кода:

"Задача UpdateProductCache отправлена после коммита транзакции"

Смотрите также

  • интерфейс ShouldQueue,
    который указывает, что задача должна быть поставлена в очередь
  • метод afterCommit,
    который устанавливает отложенную диспетчеризацию для конкретной задачи
  • интерфейс ShouldBeUnique,
    который обеспечивает уникальность задачи в очереди
  • функция dispatch,
    которая отправляет задачу в очередь
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить