Правильное использование транзакций

Использование транзакций базы данных в 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 не сработает.