Мне просто интересно, как лучше обрабатывать транзакции через несколько уровней обслуживания. Уровни службы используют ORM для хранения и извлечения из базы данных. Должны ли транзакции быть известны и обрабатываться в пределах отдельных слоев обслуживания? Или они должны обрабатываться другим слоем?
Например: у меня есть два уровня обслуживания для пользователей и клиентов. Я бы хотел:
1) Создайте и сохраните нового клиента
2) Создайте и сохраните нового пользователя
3) Назначить пользователя клиенту
Все в рамках одной транзакции.
Простой пример может выглядеть так:
$userManagementService = new UserManagementService; $newUserData = array(...); $newUser = $userManagementService->create($newUserData); $clientManagementService = new ClientManagementService; $newClientData = array(...); $newClient = $clientManagementService->create($newClientData); $userManagementService->assignUserToClient($newUser, $newClient);
Где должна идти логика транзакций?
Не пытайтесь делать вложенные транзакции в пределах уровней обслуживания или внутри ORM.
Транзакции являются глобальными для соединения с БД. Если ваша RDBMS не поддерживает вложенные транзакции изначально, а ваш DB API предоставляет вложенные транзакции, вы можете столкнуться с аномалиями.
Подробнее см. В моем ответе « Как обнаружить, что транзакция уже запущена?
Поскольку вы используете PHP, объем транзакций не более одного запроса. Поэтому вам следует просто использовать транзакции, управляемые контейнером, а не транзакцию уровня сервиса. То есть, начните транзакцию в начале обработки запроса и совершите (или откат) по мере завершения обработки запроса.
Если исключение, требующее откат, происходит глубоко внутри вложенных действий ORM, тогда пузырь, что с помощью исключения, и пусть контейнер (т. Е. Ваш контроллер действия PHP) позаботится об этом.
Вы сталкиваетесь с агрегированием транзакций? Подходит ли этот псевдокод к тому, что я думаю, что вы говорите?
try begin application transaction begin ORM transaction 1 create new user commit request begin ORM transaction 2 create new client commit request begin ORM transaction 3 create user client association commit request commit application tx catch() abort ORM tx 3 abort ORM tx 2 abort ORM tx 1 abort app tx
В любом случае откат вложенной транзакции скорее всего вызовет исключение, и эти исключения будут логически откатывать все вложенные транзакции в двухфазной фиксации .
Возможно, я не получу то, что тебе нужно.