DB::transaction() - захист даних
Переказ $100 між рахунками. Гроші списані з Аліси. Сервер падає. Боб їх ніколи не отримує.
Без транзакцій часткові оновлення пошкодять дані.
Як це працює:
Всі запити виконуються як одна атомарна одиниця. Якщо щось не вдається - все відкочується назад. База даних ніколи не опиняється в неузгодженому стані.
Три способи використання:
- Closure (рекомендовано) - автоматичний rollback при винятках
- Ручний begin/commit - коли потрібен точний контроль
- З повторами - автоматична обробка deadlock
Важливо:
Транзакції працюють тільки з InnoDB таблицями. Тримати їх короткими - вони блокують рядки. Довгі операції блокують інші запити.
Не змішувати виклики зовнішніх API з транзакціями бази даних.
// ПОГАНО: Часткове збереження при помилці
$user = User::create($data);
$profile = Profile::create(['user_id' => $user->id]);
// Якщо це не вдається, користувач існує без профілю
// ДОБРЕ: Все або нічого
DB::transaction(function () use ($data) {
$user = User::create($data);
$profile = Profile::create(['user_id' => $user->id]);
$user->sendWelcomeEmail();
});
// Ручний контроль
DB::beginTransaction();
try {
$order = Order::create($orderData);
$payment = Payment::create($paymentData);
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
throw $e;
}
// З повтором при deadlock
DB::transaction(function () {
// Код
}, 3); // Повторити 3 рази якщо deadlock