我正在尝试从其官方文档中学习laravel数据库队列。我已完成文档中给出的配置。
这是我的工作:
<?php
namespace App\Jobs;
use App\SearchLog;
use App\Jobs\Job;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendTicket extends Job implements SelfHandling, ShouldQueue
{
use InteractsWithQueue, SerializesModels;
protected $log;
protected $searchLog = array();
public function __construct(SearchLog $log , $data = array())
{
$this->log = $log;
$this->searchLog = $data;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$this->log->create($this->searchLog);
}
在我的控制器中,我这样称呼
public function store(Request $request)
{
$searchLog = array();
// searchLog contains the data to be inserted into database
$log = new SearchLog();
$this->dispatch(new SendTicket($log , $searchLog));
}
当我运行php artisan queue:listen
时,我收到错误,如
[Illuminate \ Database \ Eloquent \ ModelNotFoundException]无查询 模型[App \ SearchLog]的结果。
但是当我编辑像这样的工作时
//only edited code
public function __construct($data = array())
{
$this->searchLog = $data;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
SearchLog::create($this->searchLog);
}
来自这样的电话
public function store(Request $request)
{
$searchLog = array();
// searchLog contains the data to be inserted into database
$this->dispatch(new SendTicket($searchLog));
}
工作正常,插入数据。
在这里,我的问题是:
答案 0 :(得分:6)
问题出在use Illuminate\Queue\SerializesModels;
,它试图序列化您传递给构造函数的SearchLog $log
参数。由于您的模型尚未保存,因此它没有标识符。
根据Laravel文件:
如果您的排队作业仅在其构造函数中接受Eloquent模型 模型的标识符将序列化到队列中。什么时候 实际处理作业,队列系统将自动执行 从数据库中重新检索完整的模型实例。
解决方法是从您愿意保存模型的Job类中删除SerializesModels
特征。
答案 1 :(得分:2)
我遇到了同样的问题。
看起来如果你想将Model推送到队列中,它的ID就会被保存在有效载荷中。因此,如果您尚未保存模型,则它不会在处理程序中可用。
毕竟我在Queues and Eloquent Models中的documentation中找到了它。
要解决这个问题,我看到两个解决方案,第一个是确保你有一个持久的模型:
public function store(Request $request)
{
$searchLog = array();
// searchLog contains the data to be inserted into database
$log = new SearchLog();
//Save the Searchlog beforehand if it doesn't have any data constraints
$log->save();
//Dispatch the Job with the saved Model
$this->dispatch(new SendTicket($log , $searchLog));
}
或仅将完整的模型保存过程放入处理程序,就像您在示例中所做的那样。
//Full saving/initializing is happening here
public function handle()
{
SearchLog::create($this->searchLog);
}
在我的情况下,我必须在高性能过程中将模型保存到数据库中,所以我将它完全放在我的进程不依赖于db保存速度的处理程序中。所以我会把它放在handle()函数中。
答案 2 :(得分:1)
如果尚未保存或持久保存模型,通常会出现此问题。检查您的模型实例和持久性。可能引起此问题的另一件事是多租户。因此,如果您正在使用或构建具有多数据库的多租户应用程序,则可能需要找出一种将数据库连接传递到队列的方法,或者仅使用Tylor Otwell在此处[5.4] Support queued jobs with unpersisted models所述的数据数组。 >