来自观察者的Laravel队列任务在created() 事件之后抛出ModelNotFoundException(没有查询到模型 [Invoice] 的结果)
在从Eloquent观察者派发排队作业时,我遇到了一个问题。
Error
Illuminate\Database\Eloquent\ModelNotFoundException:
No query results for model [App\Models\Invoice]
in vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:621
#0 vendor/laravel/framework/src/Illuminate/Queue/SerializesAndRestoresModelIdentifiers.php(109):
Illuminate\Database\Eloquent\Builder->firstOrFail()
Observer Code
public function created(OrderDeliveryOption $orderDeliveryOption): void
{
info('orderDeliveryOption created' . $orderDeliveryOption);
if ($orderDeliveryOption->is_custom_label) {
Log::info('Custom label created, tracking update needed', [
'orderDeliveryOption' => $orderDeliveryOption
]);
}
UpdateOrderParcelLithiumStatusJob::dispatch($orderDeliveryOption->id)
->afterCommit()
->delay(now()->addSeconds(5));
}
Context
- 这段代码在
created()观察者对OrderDeliveryOption的实现中运行。 - 作业已被排队。
- 我只传递了
$orderDeliveryOption->id,并非完整模型。 - 但在队列处理期间,Laravel会对
App\Models\Invoice抛出ModelNotFoundException。 - 堆栈跟踪指向
SerializesAndRestoresModelIdentifiers.php。
My Questions
- 为什么在我只传递了一个整数ID的情况下,Laravel还要尝试还原
Invoice? - 在观察者模型中加载的相关模型会引起序列化问题吗?
- 这个问题很可能出在Job的构造函数/属性/特性(traits)里吗?
- 从观察者中安全派发作业的最佳实践是什么?
Additional Notes
- 作业使用
afterCommit() - 延迟时间为5 秒
- 错误仅在从观察者调用时发生
- 如果直接执行逻辑,则可以正常工作
我应该在Job类中检查哪些内容来修复此问题?
解决方案
首先,你不需要只把模型的ID传给作业,那是2016年的做法。
每个作业都会带有 Illuminate\Queue\SerializesModels trait,它只将模型的ID作为载荷。当作业从队列中弹出时,Laravel将使用该ID来检索模型。
其次,我认为你在作业中自己检索那张发票,而该发票已不存在。
你可以把下面这段代码放到你的作业里,以避免该作业失败:
public $deleteWhenMissingModels = true;
你能把那个 UpdateOrderParcelLithiumStatusJob 作业的完整源码贴到问题中吗?让我们看一看?
请确认我的假设是否正确,如有其他我可以帮忙的,请告诉我。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。