Laravel队列未将实体保存到数据库

时间:2018-11-15 13:13:55

标签: php asynchronous laravel-5 eloquent

请帮助,我可能在做或理解错了。 我正在创建大量上传到数据库的文件,这需要一点时间,所以我决定使用Laravel Queues进行所有异步操作并在后台进行处理。

在控制器中,我创建一个关联列表,该列表传递给Laravel Job。

foreach($data as $row)
    {
        $instantArray = array();
        $orderDate = \PHPExcel_Shared_Date::ExcelToPHPObject($row[3]);
        $issueDate = \PHPExcel_Shared_Date::ExcelToPHPObject($row[4]);
        $orderRow = array(
            'invoice_no' => trim($row[0]),
            'agent_id' => $row[1],
            'issued_at' => $orderDate->format('Y-m-d'),
            'received_at' => $issueDate->format('Y-m-d'),
        );
        $gameArray = array();
        $invoiceOrdersArray[] = $orderRow;
    }

$job = (new Import($invoiceOrdersArray));
dispatch($job);

在Laravel Job中,我试图创建一个枚举并将其上传到数据库

class Import implements ShouldQueue
{
  use InteractsWithQueue, SerializesModels, Queueable, Dispatchable;
  protected $importData;
  public function __construct($importData)
  {
      $this->importData = $importData;
  }

  public function handle()
  {
      foreach($this->importData as $insert)
      {
         InvoicesOrder::create($insert);
      }
}

但是,每次尝试时,我都会在日志中看到

 #0 app\Utilities\Updater.php(18): Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(8, 'Trying to get p...', '...', 18, Array)
 #1 vendor\laravel\framework\src\Illuminate\Events\Dispatcher.php(348): Modules\Accounting\Entities\InvoicesOrder::App\Utilities\{closure}(Object(Modules\Accounting\Entities\InvoicesOrder))
 #2 vendor\laravel\framework\src\Illuminate\Events\Dispatcher.php(199): Illuminate\Events\Dispatcher->Illuminate\Events\{closure}('eloquent.creati...', Array)
 #3 vendor\laravel\framework\src\Illuminate\Events\Dispatcher.php(159): Illuminate\Events\Dispatcher->dispatch('eloquent.creati...', Array, true)
 #4 vendor\laravel\framework\src\Illuminate\Database\Eloquent\Concerns\HasEvents.php(148): Illuminate\Events\Dispatcher->until('eloquent.creati...', Object(Modules\Accounting\Entities\InvoicesOrder))
 #5 vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php(636): Illuminate\Database\Eloquent\Model->fireModelEvent('creating')
 #6 vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php(522): Illuminate\Database\Eloquent\Model->performInsert(Object(Illuminate\Database\Eloquent\Builder))
 #7 Modules\Accounting\Jobs\ImportFiles.php(39): Illuminate\Database\Eloquent\Model->save()
 #8 [internal function]: Modules\Accounting\Jobs\ImportFiles->handle()
 #9 vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(29): call_user_func_array(Array, Array)
 #10 vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(87): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
 #11 vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(31): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
 #12 vendor\laravel\framework\src\Illuminate\Container\Container.php(539): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
 #13 vendor\laravel\framework\src\Illuminate\Bus\Dispatcher.php(94): Illuminate\Container\Container->call(Array)
 #14 vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(114): Illuminate\Bus\Dispatcher->Illuminate\Bus\{closure}(Object(Modules\Accounting\Jobs\ImportFiles))
 #15 vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(102): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Modules\Accounting\Jobs\ImportFiles))
 #16 vendor\laravel\framework\src\Illuminate\Bus\Dispatcher.php(98): Illuminate\Pipeline\Pipeline->then(Object(Closure))
 #17 vendor\laravel\framework\src\Illuminate\Queue\CallQueuedHandler.php(42): Illuminate\Bus\Dispatcher->dispatchNow(Object(Modules\Accounting\Jobs\ImportFiles), false)
 #18 vendor\laravel\framework\src\Illuminate\Queue\Jobs\Job.php(69): Illuminate\Queue\CallQueuedHandler->call(Object(Illuminate\Queue\Jobs\RedisJob), Array)
 #19 vendor\laravel\framework\src\Illuminate\Queue\Worker.php(317): Illuminate\Queue\Jobs\Job->fire()

每当我在控制器中执行此操作时,它都能正常工作,并且加载时间很长。 也许无法使用队列将实体保存在Job中?

谢谢。

3 个答案:

答案 0 :(得分:1)

在工作中,您将数据插入$this->importData属性中。

但是在handle方法中,您正在遍历$invoiceOrdersArray,它是从哪里来的?

您的循环应该不是这样吗?

foreach($this->importData as $insert)
{
     InvoicesOrder::create($insert);
}

您甚至不需要在handle方法中使用未使用的$order变量。

此外,我认为您需要在工作中useInvoicesOrder类。所以整个事情可能看起来像这样。

use namespace/to/InvoicesOrder;

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

    protected $importData;
    public function __construct($importData)
    {
         $this->importData = $importData;
    }

    public function handle()
    {
        foreach($$this->importData as $insert)
        {
            InvoicesOrder::create($insert);
        }
    }
}

答案 1 :(得分:0)

如果有人遇到类似问题,请检查您的实体是否正在使用任何类型的演示者(我使用的是可演示性状),该演示者会添加创建/更新者等字段。而我们从Auth :: user()-> id那里得到了什么...试图获取非对象的属性,因为队列不是用户。

答案 2 :(得分:0)

由于队列工作器是长期存在的进程,因此如果不重新启动,它们将不会对您的代码进行更改。因此,使用队列工作程序部署应用程序的最简单方法是在部署过程中重新启动工作程序。您可以通过发出queue:restart命令来正常重启所有工作线程:

protected void onPostExecute(JSONObject result) {
    try {
        if (result != null) {
            Toast.makeText(getApplicationContext(), result.getString("message"), Toast.LENGTH_LONG).show();
            Intent i = new Intent(getApplicationContext(), MainActivity.class);
            getApplicationContext().startActivity(i);
        } else {
            Toast.makeText(getApplicationContext(), "Unable to retrieve any data from server", Toast.LENGTH_LONG).show();
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}
相关问题