Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Выборка одной и той же записи таблицы скриптами, работающими параллельно. Хочу избежать. 
:(
    Опции темы
Xo6oT
Дата 26.6.2007, 21:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 6.4.2007

Репутация: нет
Всего: нет



Имеется таблица в базе данных MySQL.
Имеется скрипт на php5.
Скрипт делает следущее - извлекает из таблицы первую запись со статусом, равным 1 ("WHERE status=1").
Затем запоминает информацию, хранящуюся в этой записи (для дальнейшей обработки), в локальных переменных.
И сразу же изменяет статус (status) записи на 2 (UPDATE).

Проблема состоит в следующем - 
одновременно запускается несколько копий этого скрипта (для определенности пусть будет 10).

Так вот, эти копии извлекают ОДНУ И ТУ ЖЕ запись.
Мне нужно, чтобы первый скрипт обратился к таблице, выбрал запись, обработал ее. Второй выбрал следующую запись, третий - третью и т.д.

Если блокировать таблицу (LOCK TABLES), то скрипты, следующие за первым (но отстающие на доли секунды), начинают выдавать ошибку - нет доступа. Это логично, конечно. Но мне не хочется каждый раз перезапускать скрипт только из-за того, что ему не хватило доли секунды, пока блолкировка закончится и он обратится к очередной записи. Громоздить конструкции вроде
Код

$success = false;
while(!$success)
{
try
{
getRecord();
}
catch(Exception $e)
{
continue;
}
$success = true;
}

мне представляется не совсем правильным.

Как посоветуете по-человечески добиться нужного мне эффекта (средствами php, или mysql, или комбинированными)?
PM MAIL   Вверх
sTa1kEr
Дата 26.6.2007, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 9
Всего: 146



Если промежуток между SELECT-ом и UPDATE-ом не большой, то я бы предложил использовать транзакции, но для этого надо для таблицы выбрать движок InnoDB. Делается это достаточно просто, сначала начинаем транзакцию и выполняем запрос SELECT FOR UPDATE
Код

START TRANSACTION;
SELECT * FROM `table` WHERE `status` = 1 FOR UPDATE;

Спокойно сохраняем данные, остальные запросы, которые будут затрагивать эту строку будут спокойно ждать, пока не завершится транзакция. Затем UPDATE и завершаем транзакцию.
Код

UPDATE `table` `status` = 1 WHERE `id` = 123;
COMMIT;

В принципе можно выполнить даже одним запросом, что бы время задержки было минимальным.
PM MAIL   Вверх
Xo6oT
Дата 28.6.2007, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 6.4.2007

Репутация: нет
Всего: нет



Увы, данный подход не решает мою проблему.
Если я правильно понимаю, 
Код

SELECT ... FOR UPDATE;

запрещает UPDAT'ить запись, но не запрещает чтение из нее.
Поэтому пока мой результат такой же - несколько копий скрипта выбирают одну и ту же запись...
PM MAIL   Вверх
sTa1kEr
Дата 28.6.2007, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 9
Всего: 146



Цитата(Xo6oT @  28.6.2007,  15:07 Найти цитируемый пост)
Если я правильно понимаю, 
1: SELECT ... FOR UPDATE;
запрещает UPDAT'ить запись, но не запрещает чтение из нее.

Как раз наоборот. Эта конструкция говорит о том, что SELECT выполняется для полседующего UPDATE, а значит строка блокируется на чтение и запись до тех пор, пока не будет завершена транзакция.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Базы Данных | Следующая тема »


 




[ Время генерации скрипта: 0.0458 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.