开发者

Should my Service implements transaction & commit method?

开发者 https://www.devze.com 2023-03-05 18:25 出处:网络
Let\'s say I want to do a bulk User update in my UsersController. In my UsersController I do: foreach ($users as $user) {

Let's say I want to do a bulk User update in my UsersController.

In my UsersController I do:

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

If there are a lot of users, it can get slower because the UserService::updateUser method just do a persist()/flush()

So I'm wondering if it could be a good idea to do something like that:

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();
   }
开发者_StackOverflow}

Then in my UsersController I can do:

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

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

$userService->commit();

What are your thought?


I wouldn't want to expose any transaction-management stuff above my service layer. I'd probably shove all of that stuff down into my service, and expose two public methods updateUser(userEntity) (for a one-off with an implicit flush), and updateUsers(array-of-users) (for batch updates)

Something roughly like:

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);
    }
}

Then, if you later decide you want to chunk your updates into groups of 100, or whatever, all your bulk-update logic is nicely factored in the service, instead of in potentially multiple places in your controller(s).


Wrapping it all in a transaction will definitely speed things up.

Writing the whole bulk update as a single SQL query will be hundreds of times faster though.

0

精彩评论

暂无评论...
验证码 换一张
取 消