Запуск нескольких сценариев PHP одновременно (проблема с циклом базы данных) - PullRequest
3 голосов
/ 20 ноября 2011

Я одновременно запускаю 10 PHP-сценариев и обрабатываю их в фоновом режиме в Linux.

Например:

while ($i <=10) {
 exec("/usr/bin/php-cli run-process.php > /dev/null 2>&1 & echo $!");
 sleep(10);
 $i++;
}

В run-process.php возникла проблемас циклом базы данных.Один из процессов может уже обновить поле status до 1, кажется, что другие процессы скрипта php его не видят.Например:

$SQL = "SELECT * FROM data WHERE status = 0";
$query = $db->prepare($SQL);
$query->execute();

while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
    $SQL2 = "SELECT status from data WHERE number = " . $row['number'];
    $qCheckAgain = $db->prepare($SQL2);
    $qCheckAgain->execute();
    $tempRow = $qCheckAgain->fetch(PDO::FETCH_ASSOC);

    //already updated from other processs?
    if ($tempRow['status'] == 1) {
        continue;
    }

    doCheck($row)
    sleep(2)
}

Как мне убедиться, что процессы больше не повторяют одни и те же данные?

Ответы [ 4 ]

3 голосов
/ 20 ноября 2011

Если у вас есть несколько процессов, вам нужно, чтобы каждый процесс стал «владельцем» определенного набора записей.Обычно вы делаете это, выполняя обновление с предложением limit, затем выбирая записи, которые были просто «принадлежат» сценарию.

Например, есть поле, которое указывает, доступна ли запись для обработки (то есть значение 0 означает, что она доступна).Тогда ваше обновление установит значение поля для идентификатора процесса сценариев или какой-либо другой уникальный номер для процесса.Затем вы выбираете идентификатор процесса.Когда вы закончите обработку, вы можете установить для нее «готовый» номер, например 1. Обновить, Выбрать, Обновить, повторить.

1 голос
/ 20 ноября 2011

Я не совсем уверен, как / что вы обрабатываете.

Вы можете ввести предложение limit и передать его в качестве параметра. Итак, первый процесс выполняет первые 10, второй - следующие 10 и т. Д.

1 голос
/ 20 ноября 2011

Причина, по которой ваш скрипт выполняет один и тот же запрос несколько раз, заключается в том, что вы создаете распараллеливание. Процесс 1 читает из базы данных, Процесс 2 читает из базы данных, и оба начинают обрабатывать свои данные.

Базы данных предоставляют транзакции, чтобы избавиться от таких условий гонки. Посмотрите, что PDO предоставляет для обработки транзакций базы данных.

0 голосов
/ 20 ноября 2011

вам нужна блокировка, такая как «SELECT ... FOR UPDATE».

Блокировка уровня строки поддержки innodb.

Подробнее см. http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...