Правильное использование транзакций
Использование транзакций в Webman аналогично другим фреймворкам, здесь перечислены моменты, на которые следует обратить внимание.
Структура кода
Структура кода такая же, как и в других фреймворках, например, использование Laravel (аналогично think-orm).
Db::beginTransaction();
try {
// ..обработка бизнес-логики略...
Db::commit();
} catch (\Throwable $exception) {
Db::rollBack();
}
Здесь особенно важно использовать \Throwable
, а не использовать \Exception
, потому что в процессе обработки бизнес-логики может возникнуть Error
, который не относится к Exception
.
Подключение к базе данных
Когда вы работаете с моделями в транзакциях, особенно важно проверить, установлено ли соединение для модели. Если соединение было установлено, в момент открытия транзакции необходимо указать это соединение, иначе транзакция будет недействительна (аналогично think-orm). Например:
<?php
namespace app\model;
use support\Model;
class User extends Model
{
// Здесь указано соединение для модели
protected $connection = 'mysql';
protected $table = 'users';
protected $primaryKey = 'id';
}
Когда для модели указано соединение, открытие транзакции, подтверждение транзакции и откат транзакции должны также указывать это соединение.
Db::connection('mysql')->beginTransaction();
try {
// Обработка бизнес-логики
$user = new User;
$user->name = 'webman';
$user->save();
Db::connection('mysql')->commit();
} catch (\Throwable $exception) {
Db::connection('mysql')->rollBack();
}
Поиск запросов с неподтвержденными транзакциями
Иногда ошибки в бизнес-логике могут привести к ситуации, когда транзакция для какого-то запроса не была подтверждена. Чтобы быстро определить, какой метод контроллера не подтвердил транзакцию, вы можете установить компонент webman/log
. Этот компонент автоматически проверяет наличие неподтвержденных транзакций после завершения запроса и записывает это в журнал, ключевое слово в журнале — Uncommitted transactions
.
Метод установки webman/log
composer require webman/log
Внимание
После установки требуется перезагрузка,reload
не сработает.