Плохая ли практика оборачивать всю операцию (экшн) в транзакцию?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
i-programmer
Сообщения: 101
Зарегистрирован: 2015.08.24, 18:50

Плохая ли практика оборачивать всю операцию (экшн) в транзакцию?

Сообщение i-programmer »

На работе коллега, чтобы не заморачиваться, в beforeAction написал так:

Код: Выделить всё

public function beforeAction($action): bool {
    $transaction = Yii::$app->db->beginTransaction();
    $this->on(self::EVENT_AFTER_ACTION, [$transaction, 'commit']);

    return parent::beforeAction($action);
}
Т.е. до экшна начать транзакцию, а после экшна - применить.

------------------------

Я говорил, что лучше транзакции применять "по месту требования". Например в экшне есть много много логики, валидации модели, своя кастомная валидация и ещё что-то, и вот только когда дело доходит действительно до БД, то там и оборачивать операции в транзакции.

Нормальная ли практика оборачивать весь экшн в транзакицю? Если да - то, какие плюсы (я вижу один плюс только в одном случае). Если нет - то почему и какие минусы (я могу придумать кучку, но хотелось бы увидеть от профессионалов)?
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Плохая ли практика оборачивать всю операцию (экшн) в транзакцию?

Сообщение ElisDN »

i-programmer писал(а): 2023.07.16, 10:26 Я говорил, что лучше транзакции применять "по месту требования". Например в экшне есть много много логики, валидации модели, своя кастомная валидация и ещё что-то, и вот только когда дело доходит действительно до БД, то там и оборачивать операции в транзакции.
Именно так. Оборачивать только операции, которые записывают что-то в БД.
i-programmer писал(а): 2023.07.16, 10:26 Нормальная ли практика оборачивать весь экшн в транзакицю? Если да - то, какие плюсы (я вижу один плюс только в одном случае).
Оборачивать все экшены нет смысла, так как у actionView только SELECT-запросы. Им транзакция не нужна. Так что если и оборачивать так, то не все экшены. Для этого можно вынести это в фильтр-класс вроде Transactional по аналогии с имеющимися yii\filters\* и ему в контроллере указывать только нужные экшены:

Код: Выделить всё

public function behaviors()
{
    return [
        [
            'class' => Transactional::class,
            'only' => ['create', 'update', 'delete'],
        ],
    ];
}
Более интересно это решается выполнением всех изменяющих операций в некой шины команд Command Bus. Там транзакицей можно обернуть саму шину.
i-programmer писал(а): 2023.07.16, 10:26 Если нет - то почему и какие минусы (я могу придумать кучку, но хотелось бы увидеть от профессионалов)?
Небольшой минус оборачивания всех экшенов - это небольшое замедление сайта из-за избыточных транзакций.

Большой проблемой будет если в экшене помимо запросов в БД кто-то будет делать что-то ещё стороннее. Например, отправлять письма или ходить в сторонние сервисы по API. Тогда может получиться неприятная ситуация, что транзакция всего экшена в итоге откатилась из-за ошибки, а письмо из экшена уже ушло. Это уже решается событийной архитектурой с очередями сообщений.
Аватара пользователя
SiZE
Сообщения: 2817
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Плохая ли практика оборачивать всю операцию (экшн) в транзакцию?

Сообщение SiZE »

С таким подходом и до дедлоков рукой подать.
Ответить