4

我只是想知道如何最好地处理跨多个服务层的事务。服务层使用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); 

应该在哪里事务逻辑去?

回答

2

不要尝试在服务层或ORM中执行嵌套事务。

事务对于数据库连接是全局事务。除非您的RDBMS本身支持嵌套事务您的DB API暴露嵌套事务,否则可能会遇到异常。

有关详细信息,请参阅我的回答How do detect that transaction has already been started?

由于您使用PHP,你的交易的范围最多为一个请求。所以你应该使用容器管理的事务,而不是服务层传输。也就是说,在处理请求开始时启动事务,并在完成处理请求时提交(或回滚)。

如果一个需要回滚的异常在嵌套的ORM操作中发生,那么使用一个Exception将其冒泡,然后让容器(即PHP动作控制器)处理它。

+0

困扰,有道理。感谢这个链接,在那里有一些很好的解释。 – 2009-11-05 13:57:28

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所有嵌套事务。

我可能没有得到你想要的东西。