3

I am dispatching jobs that perform time consuming tasks when I receive a request. e.g. Send the user a welcome email when they sign up on the site

The request however dispatches the email job within a transaction and a race condition occurs. The job might execute before the transaction is committed and hence fail with a user not found error. I read about using afterCommit when dispatching the job but the doc says "Laravel will wait until all open database transactions have been committed before actually dispatching the job"

Does this mean if there are multiple transactions open from different requests, Laravel will wait for all of them to close or just the transactions related to the current request that might generated the job?

otaku
  • 849
  • 2
  • 13
  • 33

2 Answers2

0

As far as I know laravel will wait for that particular transaction in which job is created, if that transaction is child transaction then laravel will wait until parent transaction to commit. Hope this answer helped you.

0

If you do not want to set 'after_commit' => true for the whole queue and you just need one-off solution to dispatch a job after a transaction, you can try using the DB::afterCommit() hook.

DB::transaction(function () {
  // some processing

  DB::afterCommit(fn () => \App\Jobs\TestJob::dispatch());

  // some other processing if needed
})

The job will only be dispatched if the transaction is committed and not rolled back.

Arunas
  • 3
  • 2
  • While the answer might be useful, it does not actually answer the question, which is about internal behaviors of Laravel, but not asking for a solution. – Luke 10X Apr 05 '23 at 14:41
  • I agree this is not "the answer" for the question above, but someone coming here from Google might find it helpful as it's definitely related. – Arunas Apr 11 '23 at 06:33