Помогите решить проблему.
Есть файл parsing.php Он выполняет такие задачи:
1. Берет строку для парсинга из таблици A
2. Сразу же помечает эту строку как “на парсинге” (просто в поле “status_parsing” пишу “1”) – для того что бы другой поток не выбрал эту строку повторно (далее будет понятно )
3. Парсит данные
4. Заносит спарсенные данные в таблицу B
5. Запускает свою копию
Запускаю 10 копий скрипта одновременно этой функцией. Свою копию скрипт так же запускает этой функцией.
// запуск скрипта без ожидания завершения
function exec_script($url, $params = array())
{
$parts = parse_url($url);
if(!$fp = fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80))
{
return false;
}
$data = http_build_query($params, '', '&');
fwrite($fp, "POST ". (!empty($parts['path']) ? $parts['path'] : '/') ." HTTP/1.1\r\n");
fwrite($fp, "Host: ". $parts['host'] ."\r\n");
fwrite($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
fwrite($fp, "Content-Length: ". strlen($data) ."\r\n");
fwrite($fp, "Connection: Close\r\n\r\n");
fwrite($fp, $data);
fclose($fp);
return true;
}
Вот так запускаю 10 копий (это в файле start_potoks.php)
for($i=0; $i<10; $i++)
{
exec_script('http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/parsing.php', array());
sleep(6); // sleep почти не влияет на количество дублей, но если его нет то там даже не дубли...короч может быть по 5 дублей подряд
}
Все работает. НО! Разные потоки скрипта довольно часто читают одну и ту же строку из таблици A
И в итоге в таблице B записуется очень много дублей.
Думал решить этот вопрос блокировкой таблици. Но дубли все равно прут…
Вот так произвожу блокировку таблици (скорее всего неправильно. Так как дубли все рано есть)
mysql_query("LOCK TABLES keys READ, keys WRITE"); // блокируем таблицу на чтение и запись (что бы другой поток не выбрал уже выбранную строку)
$query = mysql_query("SELECT * FROM `parser`.`keys` WHERE `status` = '' LIMIT 1");
$row = mysql_fetch_assoc($query);
mysql_query("UPDATE `parser `.`keys` SET `status` = '1' WHERE `id` = ".$row['id']." LIMIT 1"); // обновляем статус у строки на "спарсено"
mysql_query("UNLOCK TABLES"); // разблокируем таблицу
Вобщем может кто знает как помочь. Может я как то неправильно блокирую таблици?