Laravel - Schema - MySql - 临时表“已经存在”

时间:2017-07-04 04:47:22

标签: mysql laravel rabbitmq message-queue temp-tables

我使用Laravel 5.4作为Web应用程序,RabbitMQ用于消息队列层,以及Laravel队列工作程序。我有两个相关的问题:

临时表

我的构造函数中有以下表创建代码:

Schema::create('tmp_products', function (Blueprint $table) {
            $table->temporary();
            $table->integer('id');
            $table->string('alias',     255);
            $table->string('include',   255)->nullable();
            $table->string('exclude',   255)->nullable();
        });

请注意

的使用
$table->temporary();

当此进程的多个实例同时运行时,我收到以下错误:

  

PDOException:SQLSTATE [42S01]:基表或视图已存在:1050表'tmp_products'已存在于/var/www/myproject/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php中: 91

起初我认为该表可能不是临时的,但是我没有在MySQL Workbench中看到该表,所以不太可能。

可能多个进程似乎是共享连接状态(因为临时表是特定于会话的)。 代码作为Laravel php artisan queue:worker命令运行,由supervisord(带numprocs=3)管理,我可以在htop中看到有三个进程具有唯一的PID,所以我不明白他们怎么能共享连接状态。

队列 - 失败的工作

更有趣的是我使用标志--tries=0运行队列工作程序(即不要重试处理消息),因此在{{1}内抛出上述异常之后消息应立即传递给Laravel job->handle()表,但我看到的是无限循环的异常,消息永远不会离开队列。

所以我想我的问题是:

  1. failed_jobs进程如何共享数据库连接状态
  2. 为什么这个特定场景会阻止消息失败,而如果我在handle()函数中明确queue:worker,那么会按预期失败
  3. 感谢任何帮助。

    谢谢,

    编辑:我弄清楚失败的工作没有进入throw new Exception();表的原因。将failed_jobs设置为零似乎可以让作业永远尝试。将其设置为1固定它。

    更新:使用原始PDO时发生同样的错误:

    --tries=0

1 个答案:

答案 0 :(得分:0)

好吧我明白了。我完全误解了Laravel工人的运作方式。在我的脑后,我假设他们像阿帕奇一样工作 - 在后台为每个工作产生一个工人 - 并在完成时摧毁每个工人。不是这种情况。每个工作程序都会侦听队列,等待并按顺序处理作业。它不会在每个作业上重新创建数据库会话。

顺便说一句,这意味着同一个错误会影响单个工作人员处理的第二个工作。

所以我上一份工作的临时表在下一份工作中仍然存在。现在我只检查,如果表存在不重新创建。

由于