我的服务应该实现交易吗?提交方法?

时间:2011-05-14 20:37:02

标签: php zend-framework design-patterns doctrine-orm service-layer

假设我想在UsersController中进行批量用户更新。

在我的UsersController我这样做:

foreach ($users as $user) {
    $userService = new UserService();
    $user->updateUser($data);
}

如果有很多用户,它可能会变慢,因为UserService :: updateUser方法只执行persist() / flush()

所以我想知道做这样的事情是不是一个好主意:

class UserService {
  public function setUseTransaction($flag)
  {
      $this->useTransaction = $flag;
      return $this;
  }

  public function updateUser($data)
  {
     // some data mapping

     $entityManager->persist($user);

     if ($this->useTransaction) {
       $entityManager->flush();
     }
   }

   public function commit()
   {
      $entityManager->flush();
   }
}

然后在UsersController我可以做到:

$userService = new UserService();
$userService->setUseTransaction(true);

foreach ($users as $user) {
    $userService = new UserService();
    $user->updateUser($data);
}

$userService->commit();

你有什么想法?

2 个答案:

答案 0 :(得分:3)

我不想在我的服务层之上公开任何交易管理内容。我可能会把所有这些东西都推到我的服务中,并公开两个公共方法updateUser(userEntity)(用于带有隐式刷新的一次性)和updateUsers(用户数组)(用于批量更新)< / p>

大致类似于:

class UserService {

    public function updateUser(User $user){
        $this->_updateUser();
        $this->em()->flush();        
    }

    public function updateUsers(array $users){
        foreach($users as $u) $this->_updateUser($u);
        $this->em()->flush();     
    }

    private function _updateUser(User $user){
        //do stuff to $user
        $this->em()->persist($user);
    }
}

然后,如果您以后决定要将更新分成100个或更多的组,那么所有批量更新逻辑都会在服务中得到很好的考虑,而不是在控制器中可能存在多个位置。< / p>

答案 1 :(得分:0)

在交易中将其全部包装一定会加快速度。

将整个批量更新编写为单个SQL查询的速度要快几百倍。