在Laravel Supervisor

时间:2018-01-08 17:45:40

标签: php mysql laravel supervisor

我需要将55个.tsv文件中的数据同时导入 MySQL数据库

我的工作是使用 updateOrCreate() 方法读取文件并更新数据库中的行。

我的主管配置:

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /Users/denis/Code/my_project/artisan queue:work --tries=3 --timeout=3600 --daemon
autostart=true
autorestart=true
numprocs=55
stdout_logfile=/Users/denis/Code/my_project/storage/logs/workers.log
stderr_logfile=/Users/denis/Code/my_project/storage/logs/workers_error.log

但是当我这样做时,所有作业都会因错误而失败:

  

PDOException:SQLSTATE [40001]:序列化失败:1213死锁   试图锁定时发现;尝试重新启动事务   /Users/denis/Code/my_project/vendor/laravel/framework/src/Illuminate/Database/Connection.php:474   ...

我可以使用try-catch块解决它

$updated = null;
$db_max_retries = 10;
$db_retry_count = 0;
while($updated == null && $db_retry_count < $db_max_retries) {
    try {
        $updated = AdsPerformance::updateOrCreate(['campaign_id' => $performance_obj['campaign_id'], 'date' => $performance_obj['date'], 'ad_provider' => 'adwords'], $performance_obj);
    } catch (\Exception $e) {
        sleep(1);
        $db_retry_count++;
    }
}
$lines_proceded++;

...但在这种情况下,该过程需要很长时间,因为在~2000个导入行中有大约200个死锁。

  • 当表为空时,没有死锁。仅当表已有数据时才会出现死锁(基本上是在尝试更新时)
  • 我尝试使用不同的睡眠时间。睡眠= 5时,死锁更少。使用sleep = 1/10秒(我使用 usleep(100000))会有更多死锁。顺便说一下,在这些情况下,总执行时间并没有太大差异。
  • 我尝试使用其他队列驱动程序(redis和beanstalkd)。但也没有太大的区别。

也许我可以尝试其他解决方案?像一些MySQL配置或其他东西?我不相信没有解决方案可以在没有死锁的情况下同时进行更新。

1 个答案:

答案 0 :(得分:0)

好的,只是意识到问题是使用复合主键。 为了解决这个问题,我使用连接的主键创建了唯一的主键列,并且没有更多的死锁。