DEV3 Technologies home

DEV3 Developer Forum

My queued job cannot find the record I just created. Why?

Laravel helpSolved0 views
dev3 ·

Inside DB::transaction I create an Order and dispatch ProcessOrder::dispatch($order). Sometimes the job fails with ModelNotFoundException, yet the order exists afterwards. Laravel 12, database queue on the same DB, Redis in production.

#laravel#queue#database

0

1 reply

dev3 · Accepted answer

This is a race between the transaction commit and the worker. The job was pushed to the queue before the transaction committed, and a fast worker (especially Redis, which is instant) picked it up and queried the order while it was still invisible to other connections.

Fix 1: dispatch after commit

ProcessOrder::dispatch($order)->afterCommit();

Laravel waits until the outermost transaction commits and discards the job if it rolls back.

Fix 2: make it the default for a connection

// config/queue.php
'redis' => [
    'driver' => 'redis',
    'after_commit' => true,
    // ...
],

Or on the job class: public $afterCommit = true;. Same options exist for events (ShouldDispatchAfterCommit), mailables and notifications.

Fix 3: dispatch outside the transaction

$order = DB::transaction(function () use ($data) {
    return Order::create($data);
});
ProcessOrder::dispatch($order);

Why the database driver does not show it

With the database queue driver on the same DB connection the job row is inside the same transaction, so it also only becomes visible at commit. That is why it only appears in production with Redis.

Related pitfalls

  • Job fails with ModelNotFoundException when a model is deleted before it runs. Add public $deleteWhenMissingModels = true; if that is acceptable.
  • In tests, Queue::fake() plus Queue::assertPushed(...) is the simplest way to assert a job was dispatched, whether or not it uses afterCommit.
  • Idempotency: assume jobs can run twice and guard with a status check.
0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.