laravel / lumen-framework

The Laravel Lumen Framework.
https://lumen.laravel.com
MIT License
1.48k stars 419 forks source link

The event of the transaction does not work when the `DB::enableQueryLog()` is on #1116

Closed andrey-helldar closed 4 years ago

andrey-helldar commented 4 years ago

Description:

Calling the static method for enabling logging does not trigger the event call.

Steps To Reproduce:

  1. Make listener:
    
    <?php

namespace App\Listeners;

use Illuminate\Database\Events\TransactionCommitted;

final class FooListener { public function handle(TransactionCommitted $event) { dd('check'); } }


2. Register event in service provider:
```php
<?php

namespace App\Providers;

use App\Listeners\FooListener;
use Illuminate\Database\Events\TransactionCommitted;
use Laravel\Lumen\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        TransactionCommitted::class => [
            FooListener::class,
        ],
    ];
}
  1. Make the command:
    
    <?php

namespace App\Console\Commands;

use Illuminate\Console\Command; use Illuminate\Support\Facades\DB;

final class Foo extends Command { protected $signature = 'foo';

protected $description = 'Command description';

public function handle()
{
    DB::transaction(function() {
        //
    });

    dd('ok');
}

}


4. Call the `php artisan foo` command and see `check` - it's ok.

![image](https://user-images.githubusercontent.com/10347617/94835014-c920de00-0419-11eb-943f-f511db2ac5e4.png)

NEXT:
5. AppServiceProvider:
```php
<?php

namespace App\Providers;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        DB::enableQueryLog();
    }
}

See: image

The commit() method: https://github.com/laravel/framework/blob/6.x/src/Illuminate/Database/Concerns/ManagesTransactions.php#L186

The Connection classs: $this->events is null https://github.com/laravel/framework/blob/6.x/src/Illuminate/Database/Connection.php#L810

I checked the same behavior in the Laravel Framework - everything works there.

andrey-helldar commented 4 years ago

I also tried to transfer the DB::enableQueryLog() method from register to boot - it does not help. The same error.

adelf commented 4 years ago

Registering event service provider before AppServiceProvider resolves the issue:

$app->register(App\Providers\EventServiceProvider::class);
$app->register(App\Providers\AppServiceProvider::class);

\DB facade call asks to resolve the database manager instance. There is:

        if ($this->app->bound('events')) {
            $connection->setEventDispatcher($this->app['events']);
        }

and app['events'] is not ready yet. So, maybe move 'events' initiation to own service provider, which will be booted before any user code?

andrey-helldar commented 4 years ago

I think this will solve my problem. I can check in the morning.

andrey-helldar commented 4 years ago

So. I have checked and cannot change the order of the service providers as it breaks the application.

BUT I created another service provider and placed it last in the init list. Moved the call to the DB::enableLogQuery() method into it.

I think this is not a bug, it's a feature. So I close the issue :)