Метод afterCommit
Метод afterCommit класса DB применяется для регистрации колбэков, которые будут вызваны после того, как текущая транзакция базы данных будет успешно зафиксирована. Первым и единственным параметром передаётся замыкание (callable), содержащее логику, которую необходимо выполнить после коммита. Если транзакция откатывается, зарегистрированные колбэки не выполняются. Данный метод особенно полезен в сочетании с фасадом DB и методом transaction.
Синтаксис
<?php
use Illuminate\Support\Facades\DB;
DB::afterCommit(function () {
// логика после успешной транзакции
});
?>
Пример
Давайте создадим нового пользователя в транзакции и отправим приветственное письмо только в случае успешного сохранения:
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use App\Mail\WelcomeMail;
use Illuminate\Support\Facades\Mail;
class UserController extends Controller
{
public function store()
{
DB::transaction(function () {
$user = User::create([
'name' => 'John Doe',
'email' => 'john@example.com',
]);
DB::afterCommit(function () use ($user) {
Mail::to($user->email)->send(new WelcomeMail($user));
});
});
return response()->json(['message' => 'User created']);
}
}
?>
В этом примере письмо будет отправлено только после того, как транзакция с созданием пользователя будет зафиксирована. Если произойдёт ошибка во время создания пользователя, транзакция откатится, и письмо не будет отправлено.
Пример
Используем метод afterCommit для обновления кэша после успешного обновления данных в базе:
<?php
namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
class ProductController extends Controller
{
public function update($id)
{
DB::transaction(function () use ($id) {
$product = Product::findOrFail($id);
$product->price = 99.99;
$product->save();
DB::afterCommit(function () use ($product) {
Cache::put('product_' . $product->id, $product, 3600);
});
});
return response()->json(['message' => 'Product updated']);
}
}
?>
После сохранения изменений в транзакции, кэш будет обновлён новыми данными только при успешном коммите.
Пример
Если используется ручное управление транзакцией с помощью методов beginTransaction, commit и rollBack, метод afterCommit также работает корректно:
<?php
namespace App\Http\Controllers;
use App\Models\Order;
use Illuminate\Support\Facades\DB;
use App\Jobs\ProcessOrderJob;
class OrderController extends Controller
{
public function store()
{
DB::beginTransaction();
try {
$order = Order::create([
'user_id' => 1,
'total' => 250.00,
'status' => 'pending',
]);
DB::afterCommit(function () use ($order) {
ProcessOrderJob::dispatch($order);
});
DB::commit();
return response()->json(['message' => 'Order created']);
} catch (\Exception $e) {
DB::rollBack();
throw $e;
}
}
}
?>
Задание будет отправлено в очередь только после успешного вызова commit. Если произойдёт исключение до коммита, транзакция будет откатана, и задание не будет отправлено.
Смотрите также
-
метод
transaction,
который выполняет замыкание в транзакции и автоматически управляет коммитом и откатом -
метод
commit,
который фиксирует текущую транзакцию -
метод
rollBack,
который откатывает текущую транзакцию -
метод
beginTransaction,
который начинает новую транзакцию базы данных