mirror of
https://github.com/avecms/AVE.cms.git
synced 2026-08-01 00:45:44 +00:00
3.2 KiB
3.2 KiB
Транзакции
Транзакции гарантируют, что группа изменений применится «всё или ничего».
Методы
DB::startTransaction(); // начать
DB::commit(); // подтвердить
DB::rollback(); // откатить
Поддерживаются вложенные транзакции (через nested_transactions — внутренние
уровни эмулируются savepoint-логикой менеджера транзакций).
Действие после commit
Внешний HTTP, отправку писем, публикацию в соцсеть и другие необратимые действия не запускайте до подтверждения БД. Зарегистрируйте callback:
DB::startTransaction();
try {
DB::Insert($orders, $order);
DB::afterCommit(function () use ($order) {
OrderNotifications::created($order);
});
DB::commit();
} catch (\Throwable $e) {
DB::rollback();
throw $e;
}
Внутри транзакции callback выполняется после успешного внешнего commit(). При
rollback() он удаляется. Если активной транзакции нет, DB::afterCommit()
выполняет callback сразу. Исключение callback журналируется и не может отменить
уже подтверждённую транзакцию, поэтому интеграция должна быть идемпотентной.
Базовый паттерн
Всегда оборачивайте тело в try/catch и откатывайте на ошибке:
DB::startTransaction();
try {
DB::Insert($orders, $order);
$orderId = (int) DB::insertId();
foreach ($items as $item) {
$item['order_id'] = $orderId;
DB::Insert($orderItems, $item);
}
DB::Update($stock, array('qty' => DB::sqlEval('qty - 1')), 'id = %i', $productId);
DB::commit();
} catch (\Throwable $e) {
DB::rollback();
throw $e; // или обработать/залогировать
}
Когда нужны
- Несколько связанных записей должны примениться вместе (заказ + позиции + остатки).
- Пакетные операции, где частичный результат недопустим.
- Перенос/пересчёт данных.
Когда не нужны
- Одиночный
INSERT/UPDATE/DELETE— он и так атомарен. - Только чтение (
SELECT).
Подводные камни
- Не забывайте
commit()— без него по завершении запроса изменения откатятся. - Не смешивайте с DDL (
ALTER,CREATE) — в MySQL они вызывают неявный commit. - Держите транзакцию короткой: не делайте внутри неё внешних HTTP-вызовов и долгих операций — это держит блокировки.