Не пытайтесь выполнять вложенные транзакции на уровнях обслуживания или в ORM.
Транзакции являются глобальными для соединения с БД. Если ваша СУБД не поддерживает вложенные транзакции изначально и , API вашего БД предоставляет вложенные транзакции, вы можете столкнуться с аномалиями.
Подробнее см. Мой ответ на Как определить, что транзакция уже была начата?
Поскольку вы используете PHP, объем ваших транзакций составляет не более одного запроса. Таким образом, вы должны просто использовать транзакции, управляемые контейнером, а не трансы уровня обслуживания. То есть начните транзакцию в начале обработки запроса и подтвердите (или откат), когда закончите обработку запроса.
Если исключение, требующее отката, происходит глубоко во вложенных действиях ORM, то создайте пузырек с помощью исключения, и пусть об этом позаботится контейнер (т.е. ваш контроллер действий PHP).