我的服务是否应该实现事务和提交方法


Should my Service implements transaction & commit method?

假设我想在我的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();

你有什么想法?

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

大致像:

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 个组或其他任何内容,则所有批量更新逻辑都会很好地分解在服务中,而不是在控制器中的多个位置。

将其全部包装在事务中肯定会加快速度。

不过,将整个批量更新编写为单个 SQL 查询的速度会快数百倍。