Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jobs with transactions within them cause this package to infinitely loop #3

Closed
DaveWishesHe opened this issue Aug 5, 2019 · 6 comments

Comments

@DaveWishesHe
Copy link

Laravel 5.7

If the job being dispatched also contains a transaction, this gets stuck in a loop and eventually errors with Maximum function nesting level of '512' reached, aborting!

Example:

MyService.php

<?php

namespace App\Services;

use App\Jobs\DummyJobWithTransaction;

class MyService
{
    public function dispatchDummyJob()
    {
        \Log::info('About to enter TX');

        \DB::transaction(function () {

            \Log::info('About to dispatch DummyJobWithTransaction');

            dispatch(new DummyJobWithTransaction());

        });
    }
}

DummyJobWithTransaction.php

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class DummyJobWithTransaction implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $afterTransactions = true;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct()
    {
        \Log::info('Dummy Dispatched.');
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        \Log::info('Dummy Handling...');

        \DB::transaction(function () {

            \Log::info('We\'re in the Job\'s TX');
            sleep(10);

        });

        \Log::info('Dummy Handled.');
    }
}

In tinker:

$s = app()->make(App\Services\MyService::class)
$s->dispatchDummyJob();

Output in logs:

==> storage/logs/laravel.log <==
[2019-08-05 11:29:13] local.INFO: About to enter TX  
[2019-08-05 11:29:13] local.INFO: About to dispatch DummyJobWithTransaction  
[2019-08-05 11:29:13] local.INFO: Dummy Dispatched.  
[2019-08-05 11:29:13] local.INFO: Dummy Handling...  
[2019-08-05 11:29:13] local.INFO: We're in the Job's TX  
[2019-08-05 11:29:23] local.INFO: Dummy Handling...  
[2019-08-05 11:29:23] local.INFO: We're in the Job's TX  
[2019-08-05 11:29:33] local.INFO: Dummy Handling...  
[2019-08-05 11:29:33] local.INFO: We're in the Job's TX  
[2019-08-05 11:29:43] local.INFO: Dummy Handling...  
[2019-08-05 11:29:43] local.INFO: We're in the Job's TX 
(and so on...)

Presumably the issue is related to the fact that Laravel's DB is a singleton, so as soon as a fresh transaction opens, the TransactionalDispatcher starts waiting for the commit.

@therezor
Copy link
Owner

therezor commented Aug 5, 2019

Are you using sync driver for jobs?

@DaveWishesHe
Copy link
Author

On my local environment, yes. I haven't put the code up anywhere to test on an alternate driver

@DaveWishesHe
Copy link
Author

I've had an experiment, and replacing TransactionalDispatcher.php line 35 like this seems to resolve the issue, but I'm unsure as to knock on impact of overriding Laravel's singleton pattern.

- $this->db = $container->make('db');
+ $this->db = clone $container->make('db');

@therezor
Copy link
Owner

therezor commented Aug 5, 2019

I think the issue is because you are using sync queue.
It won't happened on real workers cause every worker run single instance of db.
But this case should be handled also. Please try redis as queue provider.
Cloning db object is not a good idea at all

@DaveWishesHe
Copy link
Author

DaveWishesHe commented Aug 5, 2019

Yeah, works fine on the redis queue driver, will just crack on with the "it'll work up on the other environments" for now, thanks :)

@therezor
Copy link
Owner

Fixed in 0.4.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants