clo*_*986 7 php mysql laravel eloquent laravel-4
我不知道为什么我遇到这个错误.
我有以下脚本:
foreach($brands as $brand){ // about 600items for this loop
....
....
DB::table('mailing_list')->insert(array(
'email' => $email,
'source' => $source,
'source_url'=> $brand->external_url,
'facebook_url' => $facebook_url,
'instagram_id' => $instagram_username,
'instagram_url' => $instagram_url,
'instagram_followers' => $instagram_followers
));
}
它始终在同一个项目中打破
Error while sending STMT_PREPARE packet. PID=2 (SQL: insert into `mailing_list` (`email`, `source`, `source_url`, `facebook_url`, `instagram_id`, `instagram_url`, `instagram_followers`) values (some@email.com, source, www.url.com, https://www.facebook.com/url, some_username, http://instagram.com/url, 501))
在我执行29个查询之前,现在是34个.
我想更好地理解这个错误:它可能是单个条目打破它,但即使我发布的数据是胡言乱语,实际的看起来很好.
我做了什么:
set_time_limit(3600);
DB::connection()->disableQueryLog();
DB::reconnect(Config::get('database.default')); // this one after each foreach loop
问题的真正原因和解决方案可以在我的博客文章中找到:
Laravel 4和“发送STMT_PREPARE数据包时出错”
这里不可能描述整个答案,但是长话短说,Laravel 4的\Illuminate\Database\MySqlConnection班级中存在一个错误。具体来说,其causedByLostConnection方法如下所示:
/**
* Determine if the given exception was caused by a lost connection.
*
* @param \Illuminate\Database\QueryException
* @return bool
*/
protected function causedByLostConnection(QueryException $e)
{
return str_contains($e->getPrevious()->getMessage(), 'server has gone away');
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,“服务器已消失”不是唯一表明与MySQL失去连接的消息。
Laravel 5中的相同方法会检查6条其他消息,从而解决了该问题:
/**
* Determine if the given exception was caused by a lost connection.
*
* @param \Exception $e
* @return bool
*/
protected function causedByLostConnection(Exception $e)
{
$message = $e->getMessage();
return Str::contains($message, [
'server has gone away',
'no connection to the server',
'Lost connection',
'is dead or not enabled',
'Error while sending',
'decryption failed or bad record mac',
'SSL connection has been closed unexpectedly',
]);
}
Run Code Online (Sandbox Code Playgroud)
我通过减少传递给 foreach 循环的项目解决了这个问题。
$all_brands = 品牌::all();
$填充= 0;
$批次 = 100;
while($all_brands->count() > $padding){
$brands = Brand::orderBy('id', 'asc')->skip($padding)->take($batch)->get();
foreach($品牌作为$品牌){
....
....
DB::table('mailing_list')->插入(数组(
'电子邮件' => $电子邮件,
'源' => $源,
'source_url'=> $brand->external_url,
'facebook_url' => $facebook_url,
'instagram_id' => $instagram_用户名,
'instagram_url' => $instagram_url,
'instagram_followers' => $instagram_followers
));
}
$填充=$填充+$批处理;
}