我只是想知道如何最好地处理多个服务层之间的交易。服务层使用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);
交易逻辑应该去哪里?
答案 0 :(得分:3)
不要尝试在服务层或ORM中执行嵌套事务。
事务是数据库连接的全局事务。除非您的RDBMS本身支持嵌套事务和您的DB API公开嵌套事务,否则您可能会遇到异常。
有关详细信息,请参阅我对How do detect that transaction has already been started?
的回答由于您使用的是PHP,因此您的交易范围最多只是一个请求。所以你应该只使用容器管理的事务,而不是服务层transa。也就是说,在处理请求开始时启动事务,并在完成处理请求时提交(或回滚)。
如果需要回滚的异常发生在嵌套的ORM操作中,请使用Exception将其冒泡,然后让容器(即您的PHP动作控制器)处理它。
答案 1 :(得分:1)
您是否面临交易聚合?这个伪代码是否符合我的想法?
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
在任何时候,嵌套事务的回滚都可能抛出异常,这些异常会在逻辑上回滚two-phase commit中的所有嵌套事务。
我可能没有得到你之后的东西。