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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Одновременное выполнение операции, нужна блокировка или... 
:(
    Опции темы
quiz
Дата 8.10.2007, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Здравствуйте.
Помогите, пожалуйста, справиться с проблемой, голову уже сломал smile 

Суть проблемы - на сервере есть скрипт, который в процессе выполнения достает значение "calc_done" из mysql-таблицы и если это значение == 0, то начинает выполнять довольно массивные циклы математических операций, SELECT-UPDATE таблиц и т.п. 

Когда скрипт запускается одним человеком - все окей. Но когда его одновременно выполняют десятки людей, то те самые массивные операции начинают время от времени дублироваться. Видимо скрипт запускается 1 раз и пока апдейт значения calc_done=1 не произведен, кто-либо успевает запустить этот же скрипт еще раз.

Апдейт значения делаю сразу же после условия, но это не помогает

Код

$exm= mysql_query("SELECT * FROM test WHERE myid=1");
$exm = mysql_fetch_array($exm);    
if ($exm[calc_done]==0) {
   mysql_query("UPDATE test SET calc_done=1 WHERE myid=1");

   .....................................
   массивная куча кода...
   .....................................

}



Мануал MySQL по блокировке таблиц читал - частично понял, частично нет. Пробовал расставить блокировки - не помогло. Может не так делал, а может в моем случае нужны вовсе не блокировки таблиц?
PM MAIL   Вверх
chin
Дата 8.10.2007, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Добавьте еще одно поле типа calc_process, перед началом просчета ставьте туда 1, после окончания, сбрасывайте на 0. Измените выражение на
Код

if ($exm['calc_done'] == 0 && $exm['calc_process'] == 0) {

Заключайте в кавычки ключи массивов.

Хотя, если у Вас сразу идет обновление calc_done = 1, то никакой скрипт не успеет прошустрить в этот короткий интервал. Разве что, если у Вас тормозит БД и запрос на update проходит очень долго.
Таблица test не обновляется в Вашей "массивной куче кода"?

Это сообщение отредактировал(а) chin - 8.10.2007, 22:06
PM MAIL   Вверх
quiz
Дата 8.10.2007, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



то есть так?

Код

$exm= mysql_query("SELECT * FROM test WHERE myid=1");
$exm = mysql_fetch_array($exm);    

mysql_query("UPDATE test SET calc_process=1 WHERE myid=1");

if ($exm['calc_done'] == 0 && $exm['calc_process'] == 0) {
   mysql_query("UPDATE test SET calc_done=1 WHERE myid=1");

   .....................................
   массивная куча кода...
   .....................................

}
mysql_query("UPDATE test SET calc_process=0 WHERE myid=1");


А в чем смысл? Ведь calc_done=1 присваивается почти там же, на 2 строки выше

И чем плохи ключи массивов без кавычек?

Добавлено через 3 минуты и 32 секунды
Цитата(chin @ 8.10.2007,  22:02)
Хотя, если у Вас сразу идет обновление calc_done = 1, то никакой скрипт не успеет прошустрить в этот короткий интервал. Разве что, если у Вас тормозит БД и запрос на update проходит очень долго.
Таблица test не обновляется в Вашей "массивной куче кода"?

Нет, таблица обновляется только calc_done=1

Это сообщение отредактировал(а) quiz - 8.10.2007, 22:07
PM MAIL   Вверх
chin
Дата 8.10.2007, 22:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ладно, давайте померяем:
Код

$time = array();

$time['select'] = array_sum(explode(" ", microtime()));
$exm= mysql_query("SELECT * FROM test WHERE myid=1");
$exm = mysql_fetch_array($exm);
$time['select'] = array_sum(explode(" ", microtime())) - $time['select'];

$time['update'] = array_sum(explode(" ", microtime()));
if ($exm['calc_done'] == 0 && $exm['calc_process'] == 0) {
   mysql_query("UPDATE test SET calc_done=1 WHERE myid=1");
   $time['update'] = array_sum(explode(" ", microtime())) - $time['update'];
   print_r($time);
   exit;

PM MAIL   Вверх
quiz
Дата 8.10.2007, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



select 0.00094389915466309
update 0.0024709701538086
PM MAIL   Вверх
chin
Дата 8.10.2007, 23:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Мда, ну за такое время мало что может случиться...
Уберите calc_process, он уже не поможет ;)
Кажется, тайна кроется в "массивной куче кода"...
PM MAIL   Вверх
quiz
Дата 8.10.2007, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



действительно, в такое время 2 клиента вряд ли уложиться сумеют. Ищу ошибку в коде
PM MAIL   Вверх
quiz
Дата 9.10.2007, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



нашел ошибку, спасибо

Это сообщение отредактировал(а) quiz - 9.10.2007, 22:33
PM MAIL   Вверх
chin
Дата 9.10.2007, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



и в чем же была ошибка?
PM MAIL   Вверх
theworldcreator
Дата 10.10.2007, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 362
Регистрация: 25.8.2007
Где: Москва

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



А почему не может быть так, что два скрипта одновременно запросили calc_done равный нулю(mysql их по очереди выполнит) и стали дальше выполняться - оба поочереди поставят calc_done=1 ну и станут выполнять массивную кучу кода? Маловероятно, но возможно.
PM MAIL WWW ICQ   Вверх
solenko
Дата 10.10.2007, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



quiz:
Цитата

И чем плохи ключи массивов без кавычек?

Если я правильно понимаю, то при обращении без кавычек вы пытаетесь обратиться к константе, которой не существует, а значит php ее создает и присваивает ей строку с ее именем.
попробуйте error_reporting(E_ALL);


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
quiz
Дата 10.11.2007, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(theworldcreator @ 10.10.2007,  11:50)
А почему не может быть так, что два скрипта одновременно запросили calc_done равный нулю(mysql их по очереди выполнит) и стали дальше выполняться - оба поочереди поставят calc_done=1 ну и станут выполнять массивную кучу кода? Маловероятно, но возможно.

Так оно и оказалось :(

Когда посетителей, выполняющих скрипт немного - то все ок.
Когда посетителей становится много, скорость запросов к базе резко падает и постоянно в этот промежуток (calc_done=0) попадают 2-3-4 пользователя. Соответственно код выполняется более, чем 1 раз :(

Поэтому проблема все еще актуальна - помогите найти выход, пожалуйста
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




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


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

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