php - Model Observer issue in nested transaction update of model - Stack Overflow

class ExampleUserService{public function approve($user, $data){$approvedUser = DB::transaction(functio

class ExampleUserService
{

    public function approve($user, $data)
    {

        $approvedUser = DB::transaction(function () use ($user, $data) {
            if ($data['approve_by_admin'] == 1) {
                $this->updateAdminStatus($user);
            }

            $user->update(['approved' => 1]); // This fires updated event
        });
    }

    public function updateAdminStatus($user, $data)
    {
        $user = DB::transaction(function () use ($user, $data) {

            //Some Logic

            $user->update(['status' => 5]); // This doesn't fire event
        });
    }
}

I have Scenario like above where same model gets updated in nested transactions but observer get only changes of last transaction, i want to get all updates in observer for same model.

class ExampleUserService
{

    public function approve($user, $data)
    {

        $approvedUser = DB::transaction(function () use ($user, $data) {
            if ($data['approve_by_admin'] == 1) {
                $this->updateAdminStatus($user);
            }

            $user->update(['approved' => 1]); // This fires updated event
        });
    }

    public function updateAdminStatus($user, $data)
    {
        $user = DB::transaction(function () use ($user, $data) {

            //Some Logic

            $user->update(['status' => 5]); // This doesn't fire event
        });
    }
}

I have Scenario like above where same model gets updated in nested transactions but observer get only changes of last transaction, i want to get all updates in observer for same model.

Share Improve this question edited Mar 15 at 11:58 hakre 198k55 gold badges450 silver badges856 bronze badges Recognized by PHP Collective asked Mar 13 at 7:43 Dilip ThakreDilip Thakre 111 silver badge1 bronze badge
Add a comment  | 

1 Answer 1

Reset to default 1

Laravel waits until all transactions are finished before it triggers any observer events. This means if you update a model several times within nested transactions, only the last update’s change will trigger the observer.

To fix this -> Separate the transactions so that each update commits independently

    public function approve(User $user, array $data)
    {
        if ($data['approve_by_admin'] == 1) {
            $this->updateAdminStatus($user);
        }

        DB::transaction(function () use ($user) {
            $user->update(['approved' => 1]); 
        });
    }

And there are few issues/typos:

  1. Class name should be ServiceA not Service A

  2. Wrap the whole data in a single array

     $user->update(['approved' => 1]); # not $user->update(['approved'] => 1);
     $user->update(['status' => 5]);   # not $user->update(['status'] => 5);
    
  3. in updateAdminStatus($user){ your're passing one param $this->updateAdminStatus($user);, why this has two use ($user, $data) {

     public function updateAdminStatus(User $user)
     {
         DB::transaction(function () use ($user) {
             $user->update(['status' => 5]); 
         });
     }
    

FYI: Model Observer is kinda different what you have tried here. In short its like event-listener. Official doc

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744714741a4589549.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信