Избегание одновременного выполнения скрипта

uaperson

Новичок
Всем доброго дня!
Есть такой вопрос острый по принципу написание скрипта, в котором не происходило бы одновременного выполнения взаимозависимых операций.
Объясняю подробнее:

PHP:
<?php

$q = "SELECT status FROM table WHERE id='2'";
$conn = mysql_query($q);
$row = mysql_fetch_assoc($conn);

if($row{"status"}==0) {
// Какой-то код действий, который выполняет 15 секунд.
// обновляем статус
mysql_query("UPDATE table SET status='1' WHERE id='2'");
}
else die("Error");
получается, что если в течении 15 секунд, пока выполняется код-действие и еще не обновился статус, произойдет еще один запрос к этому скрипту, то он сможет выполниться второй раз, хотя по алгоритму это действие должно происходить всего лишь один раз. Как можно этого избежать?

Эта проблема преследует меня в разных вариантах и без БД, в том числе, и я не могу придумать 100% решения, которое будет проверять действительно актуальный статус. Надежда только на вашу помощь.

Прошу не предлагать вариант, поставить UPDATE перед кодом-действием, так как есть ситуации, где UPDATE обновляет не статус, а устанавливает рассчитанное значение, сформированное кодом-действием.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Что тебе мешает обновить статус ДО этих действий?
Что тебе мешает ввести еще один статус 2 == строка в обработке ?
 

С.

Продвинутый новичок
Есть система блокировок.
Есть трансакции.
И даже на крайний случай UPDATE перед кодом-действием условным статусом "в работе" тоже не исключается.
 

uaperson

Новичок
По поводу обновления статуса: А что если скрипт выполняется совсем одновременно в одну секунду, и проверка на статус проходит одновременно, как тогда меняющийся статус ниже повлияет на ограничение выполнение скрипта второй раз?
По транзакциям: используются MyISAM таблицы и жертвовать производительностью всего проекта, ради решения этой задачи не совсем разумно, получается.
По системе блокировок: что имеется ввиду?
 

С.

Продвинутый новичок
По поводу обновления статуса: А что если скрипт выполняется совсем одновременно в одну секунду, и проверка на статус проходит одновременно, как тогда меняющийся статус ниже повлияет на ограничение выполнение скрипта второй раз?
Скрипты конечно могут исполняться в один момент, но запросы к базе -- однозначно нет.
 

uaperson

Новичок
Скрипты конечно могут исполняться в один момент, но запросы к базе -- однозначно нет.

а что если:
PHP:
<?php
// 
// 2) Второй запрос проверяет статус после первого
//
$q = "SELECT status FROM table WHERE id='2'";
$conn = mysql_query($q);
$row = mysql_fetch_assoc($conn);

//
// 1) Первый запрос выполнил проверку и проверяет условие в PHP, но еще не обновил статус
//
if($row{"status"}==0) {
// обновляем статус
mysql_query("UPDATE table SET status='1' WHERE id='2'");
// Какой-то код действий, который выполняет 15 секунд.
}
else die("Error");
как тогда? статус ведь все равно не обновлен и второй запрос проходит.
 

darkthor

Новичок
SELECT FOR UPDATE не подойдет? как незатратно защититься от второго выполнения скрипта не знаю, но с FOR UPDATE по крайней мере записать второй раз в базу не сможет.
И кстати советую с MyISAM перебираться на InnoDB
 

С.

Продвинутый новичок

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
По транзакциям: используются MyISAM таблицы и жертвовать производительностью всего проекта, ради решения этой задачи не совсем разумно, получается.
Ну вот такая трагичная ситуация: нормальные люди для решения проблемы используют транзакции, фанаты MyISAM придумывают метод удаления гланд через анус.
 

fixxxer

К.О.
Партнер клуба
Про офигенную производительность MyISAM в условиях пачки конкурентных select / UID - операций (ну как минимум в этом примере оно так) очень интересно послушать :D

А вообще, тут спокойно можно обойтись без транзакций, просто проверять, сколько там rows updated.
 
Сверху