Ой, ничего не найдено!

К сожалению, по вашему запросу пока ничего нет (но это только пока!), зато вы можете подписаться на нашу замечательную email-рассылку, чтобы не пропустить самое интересное в будущем.

  • 439

Laravel Observers и ShouldHandleEventsAfterCommit: зачем и как использовать

  • 2 минуты на чтение

Когда вы работаете с Laravel и его Eloquent-моделями, нередко возникает желание автоматически выполнять определённые действия после создания, обновления или удаления записей в базе данных. Именно для этого в Laravel существуют Observers.

Однако, как только в игру вступают транзакции, появляется риск: обработчики в обсервере могут сработать до того, как изменения будут окончательно сохранены в базе. Это может привести к различным багам и побочным эффектам.

В этой статье я разберу:

  • Что такое транзакции в Laravel
  • Как работают observers
  • Почему важно использовать ShouldHandleEventsAfterCommit
  • Жизненные примеры с багами и их исправлением

Что такое транзакция в Laravel?

Транзакция — это механизм, позволяющий выполнять несколько запросов к базе данных как одну операцию. Если хотя бы один из запросов завершится с ошибкой, все изменения откатываются.

Пример:

use Illuminate\Support\Facades\DB; DB::transaction(function () { $user = User::create([...]); $user->profile()->create([...]); // Ошибка, всё откатится throw new \Exception('Ошибка!'); });

В этом коде создаётся пользователь и его профиль. Но если происходит ошибка, база данных откатит оба действия. Это удобно и безопасно — если только никакие побочные эффекты не произошли раньше времени.

Старт без оплаты
Месяц хостинга бесплатно для новых проектов
Разместите сайт, проверьте скорость и оцените удобство Siteko.net. Просто выберите тариф и начните тестовый месяц.
Посмотреть тарифы

Как работают Observers

Observers — это классы, которые реагируют на события модели: created, updated, deleted и т.д.

Пример:

class UserObserver { public function created(User $user): void { Mail::to($user->email)->send(new WelcomeMail($user)); } }

Такой обработчик автоматически отправит письмо новому пользователю после создания записи в базе.

Проблема: Observer срабатывает до завершения транзакции

Если вы создаёте пользователя внутри DB::transaction(...), Laravel по умолчанию немедленно вызывает created(), даже если транзакция ещё не завершена.

Пример бага:

DB::transaction(function () { User::create([ 'email' => 'test@example.com' ]); throw new \Exception('Ошибка!'); });

Если в UserObserver прописано:

public function created(User $user): void { Mail::to($user->email)->send(...); }

То письмо уже отправится, хотя транзакция будет откатана и пользователь в базу не попадёт.

Подключение за минуту
Попробуйте Siteko.net бесплатно в течение месяца
Проверьте хостинг на реальном сайте: скорость, стабильность и поддержка доступны сразу после подключения.
Начать бесплатно

Решение: ShouldHandleEventsAfterCommit

Laravel позволяет "задерживать" вызов обработчиков до завершения транзакции с помощью интерфейса:

use Illuminate\Contracts\Events\ShouldHandleEventsAfterCommit; class UserObserver implements ShouldHandleEventsAfterCommit { public function created(User $user): void { // Этот код выполнится только после успешного commit'а } }

Теперь, если транзакция откатится — created() не будет вызван вовсе. Если commit прошёл — вызов произойдёт сразу после него.

Жизненные примеры использования

1. Создание связанных моделей

public function created(User $user): void { $user->profile()->create([...]); }

Без интерфейса: профиль может быть создан, а пользователь — нет (если транзакция откатится).

С интерфейсом: создаётся только если всё успешно.

2. Аудит и логирование

AuditLog::create([ 'action' => 'created user', 'user_id' => $user->id, ]);

Без интерфейса: в логе будет запись о пользователе, которого нет.

3. Уведомления и письма

Notification::send($user, new WelcomeNotification());

Без интерфейса: уведомление отправится, даже если пользователь не сохранён.

Подключение за минуту
Попробуйте Siteko.net бесплатно в течение месяца
Проверьте хостинг на реальном сайте: скорость, стабильность и поддержка доступны сразу после подключения.
Начать бесплатно

Когда стоит использовать ShouldHandleEventsAfterCommit?

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

  • Отправляются письма или уведомления
  • Создаются связанные модели
  • Пишется лог/аудит
  • Обновляются внешние API, кеши, очереди

Вывод

ShouldHandleEventsAfterCommit — это мощный инструмент для корректной работы ваших Observer'ов в Laravel, особенно при использовании транзакций. Он помогает избежать побочных эффектов и багов, которые тяжело отследить.

Если вы ещё не используете этот интерфейс — самое время внедрить его в те Observer'ы, где есть внешние действия.

Первый месяц бесплатно

Хостинг Siteko.net для стабильного запуска сайта

Разместите проект на Siteko.net и проверьте скорость, панель управления и поддержку без стартовой оплаты.

  • 1 месяц бесплатно для новых клиентов сразу после выбора тарифа.
  • Быстрый старт для лендинга, блога или корпоративного сайта.
  • Поддержка рядом поможет с переносом и настройкой проекта.
Выбрать тариф