多个服务层和数据库事务

时间:2009-10-27 21:47:02

标签: php database design-patterns transactions domain-driven-design

我只是想知道如何最好地处理多个服务层之间的交易。服务层使用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 个答案:

答案 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中的所有嵌套事务。

我可能没有得到你之后的东西。