代码之家  ›  专栏  ›  技术社区  ›  rr.

多服务层与数据库事务

  •  4
  • rr.  · 技术社区  · 15 年前

    我只是想知道如何最好地处理跨多个服务层的事务。服务层使用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 回复  |  直到 11 年前
        1
  •  3
  •   Community Neeleshkumar S    7 年前

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

    事务对数据库连接是全局的。除非RDBMS本机支持嵌套事务 您的DBAPI公开嵌套事务,您可能会遇到异常情况。

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

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

    如果需要回滚的异常发生在嵌套ORM操作的深层,那么使用异常将其冒泡,并让容器(即您的PHP操作控制器)来处理它。

        2
  •  1
  •   memnoch_proxy    15 年前

    您是否面临交易汇总?这个伪代码和我想你说的相符吗?

    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 .

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