最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin0浏览0评论
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

发布评论

评论列表(0)

  1. 暂无评论