Правильное использование транзакций
Использование транзакций базы данных в 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';
}
Когда у модели указано подключение, его нужно указывать при begin, commit и rollback:
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
Примечание
После установки нужен перезапуск (restart); reload не сработает.