Laravel: транзакция и afterCommit
Задание, которое читает новую запись, отправляйте после фиксации транзакции.
Плохо
DB::transaction(function () use ($data) {
$order = Order::create($data);
SendReceipt::dispatch($order->id);
});
Хорошо
DB::transaction(function () use ($data) {
$order = Order::create($data);
SendReceipt::dispatch($order->id)->afterCommit();
});
Почему это важно
Worker может начать работу до commit. При rollback уведомление о несуществующем заказе не должно отправиться.
Когда применять
Laravel 12.x и асинхронная очередь. Плохой пример предполагает after_commit=false в конфигурации соединения. При after_commit=true Laravel уже откладывает отправку до commit; явный afterCommit() тогда не обязателен. afterCommit() не гарантирует доставку при падении процесса между commit и отправкой; для такой гарантии нужен outbox. Обработчик всё равно должен переносить повторы.
Кто что делает
Человек
Определяет необходимую гарантию доставки и срок уведомления.
AI-агент
Настраивает afterCommit, идемпотентность и проверку rollback; для надёжной доставки реализует outbox.
Пример применения
После создания заказа квитанция ставится в очередь. Её ключ уникальности — идентификатор заказа и тип уведомления; временная ошибка почты допускает повтор.
Как проверить у себя
- Rollback не создаёт отправку.
- Повтор задания не отправляет вторую квитанцию.
Первоисточники
История изменений на GitHubДата проверки отражает содержательную сверку. Синхронизация сайта не обновляет её автоматически.