У меня есть PHP script, который извлекает строки из базы данных и затем выполняет работу на основе содержимого. Работа может занять много времени (но не обязательно вычислительно дорого), и поэтому мне нужно разрешить параллельное выполнение нескольких сценариев.
Строки в базе данных выглядят примерно так:
+---------------------+---------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+---------------+------+-----+---------------------+----------------+
| id | bigint(11) | NO | PRI | NULL | auto_increment |
.....
| date_update_started | datetime | NO | | 0000-00-00 00:00:00 | |
| date_last_updated | datetime | NO | | 0000-00-00 00:00:00 | |
+---------------------+---------------+------+-----+---------------------+----------------+
My script в настоящее время выбирает строки с самыми старыми датами в date_last_updated
(который обновляется после завершения работы) и не использует date_update_started
.
Если бы я должен был запускать несколько экземпляров script параллельно параллельно, они будут выбирать одни и те же строки (по крайней мере, некоторое время), и будет выполняться дублирующаяся работа.
То, что я собираюсь сделать, это использовать транзакцию для выбора строк, обновить столбец date_update_started
, а затем добавить условие WHERE
в оператор SQL, выбрав строки, чтобы выбирать только строки с date_update_started
больше чем какое-либо значение (чтобы еще один script не работал над ним). Например.
$sth = $dbh->prepare('
START TRANSACTION;
SELECT * FROM table WHERE date_update_started > 1 DAY ORDER BY date_last_updated LIMIT 1000;
UPDATE table DAY SET date_update_started = UTC_TIMESTAMP() WHERE id IN (SELECT id FROM table WHERE date_update_started > 1 DAY ORDER BY date_last_updated LIMIT 1000;);
COMMIT;
');
$sth->execute(); // in real code some values will be bound
$rows = $sth->fetchAll(PDO::FETCH_ASSOC);
Из того, что я прочитал, это, по сути, реализация очереди и, похоже, в MySQL недоверчива. Тем не менее, мне нужно найти способ позволить нескольким сценариям работать параллельно, и после исследования, которое я сделал, это то, что я придумал.
Будет ли работать этот тип подхода? Есть ли лучший способ?