Пишу на php+mysql.
Но никак не могу разрешить свои вопросы, помогите пожалуйста.
Успешное выполнение INSERT, UPDATE, DELETE запросов советуют проверять функцией mysql_affected_rows(), а запрос SELECT - mysql_num_rows().
В итоге если следовать этому совету код у меня выглядит примерно так:
"INSERT INTO...
if(mysql_affected_rows() == 1)
{ SELECT * FROM...
if(mysql_num_rows())
{
"UPDATE...
if(mysql_num_rows() != 1)
{
$error = true;
}
else
{
$added = true;
}
}
else $error = true;
}
else $error = true;
Т.е. сплошные if'ы.
Плюс, насколько я понимаю, если где-то случилась ошибка, мне нужно самой откатывать всю транзакцию и восстанавливать исходное состояние, а если и тут случится ошибка во время выполнения, тогда что?... замкнутый круг...
Посоветуйте пожалуйста как правильно и эффективно обрабатывать результаты запросов?
И как делать откаты транзакций, какой эффективный способ?
Переходить на ООП плиз не предлагайте, это для меня тееемный лес, не потяну...
Спустя 1 час, 19 минут, 28 секунд (26.01.2011 - 22:54) inpost написал(а):
А что именно ты обновляешь после вставки?
Спустя 9 минут, 54 секунды (26.01.2011 - 23:04) lucasa написал(а):
inpost, другие таблицы...
Спустя 16 минут, 28 секунд (26.01.2011 - 23:21) lovesa написал(а):
хорошо бы было получить весь код с самими запросами и структурой таблиц, плюс логика, что куда и зачем происходит. Песочницы в php и mysql сколько я знаю нет, по этому просто придется оптимизировать код по принципу графов
Спустя 10 минут, 57 секунд (26.01.2011 - 23:32) inpost написал(а):
lovesa
Какие вы похожие =)
lucasa
Покажи этот полный участок. С первого взгляда непонятно что да как =)
Какие вы похожие =)
lucasa
Покажи этот полный участок. С первого взгляда непонятно что да как =)
Спустя 5 минут, 37 секунд (26.01.2011 - 23:37) lovesa написал(а):
Цитата |
Какие вы похожие =) |
Да, свезло так свезло =)
Спустя 23 секунды (26.01.2011 - 23:38) lucasa написал(а):
код выкладывать не хотелось бы.
пример выше показала...
логика ничем выдающимся не отличается, стандартный набор любого веб-сервиса...
пример выше показала...
логика ничем выдающимся не отличается, стандартный набор любого веб-сервиса...
Спустя 59 секунд (26.01.2011 - 23:39) lucasa написал(а):
inpost, ща, попробую отформатировать
Спустя 1 минута, 33 секунды (26.01.2011 - 23:40) lovesa написал(а):
Цитата |
логика ничем выдающимся не отличается, стандартный набор любого веб-сервиса... |
В стандартной логике стараются сделать так, что бы был критичный запрос, перед выполнением которого делают всяческие проверки. Редко встречал места где необходимо было бы делать несколько параллельных на столько критичных запроса, что при невыполнении одного пришлось бы откатывать другой =)
Спустя 11 минут, 39 секунд (26.01.2011 - 23:52) lucasa написал(а):
if(isset($_POST['Btn'],$_POST['Id'],$_POST['Result']))
{
$sqlResult = mysql_query("SELECT * FROM `results` WHERE `id`='".mysql_real_escape_string($_POST['Id'])."'");
if(mysql_num_rows($sqlResult) == 1)
{
$result = mysql_fetch_assoc($sqlResult);
if($result)
{
if(mysql_num_rows(mysql_query("SELECT * FROM `result_user_view` WHERE `resultid`='".
mysql_real_escape_string($result['id'])."' AND `status`!='2'")) == $result['total_results_count'])
{
mysql_query("UPDATE `results` SET `status`='2' WHERE `id`='".mysql_real_escape_string($result['id'])."'");
if(mysql_affected_rows() != 1)
{
$error = true;
}
else
{
$added = false;
}
}
else
{
$createdDate = mysql_real_escape_string(gmdate($cfgFormat, time()));
mysql_query("INSERT INTO `result_user_view`(`resultid`,`email`,`result`,`status`,`date`)
VALUES('".mysql_real_escape_string($_POST['Id'])."','"
.mysql_real_escape_string($_SESSION['userlogin']).
"','".mysql_real_escape_string($_POST['Result'])."','1','".$createdDate."')");
if(mysql_affected_rows() == 1)
{
mysql_query("UPDATE `results` SET `total_results_count`='".($result['total_results_count']+1)."' WHERE `id`='".mysql_real_escape_string($result['id'])."'");
if(mysql_affected_rows() != 1)
{
$error = true;
}
else
{
$added = true;
}
}
else $error = true;
}
}
else $error = true;
}
}
как-то так...
Спустя 1 минута, 29 секунд (26.01.2011 - 23:53) lucasa написал(а):
lovesa
а критичный запрос один подразумевается?
а критичный запрос один подразумевается?
Спустя 2 минуты, 2 секунды (26.01.2011 - 23:55) lovesa написал(а):
Цитата |
а критичный запрос один подразумевается? |
один =) но если все же есть нужда рабоать как в песочнице, то есть классная фича как transactions, можно почитать например тут http://www.devarticles.com/c/a/MySQL/Using...QL-4.0-and-PHP/
Спустя 2 минуты, 23 секунды (26.01.2011 - 23:58) lucasa написал(а):
lovesa спасибо)
а альтернативы на русском случайно нет?
а альтернативы на русском случайно нет?

Спустя 4 минуты, 19 секунд (27.01.2011 - 00:02) lovesa написал(а):
Просмотрел код, не вижу особых мест где откат необходимо делать =) ну по сути в коде присутвует 2 update совершенно в разных местах, update не делается в купе ни с каким запросом, все проверки происходят до самого апдейта, как следствие если где-то что-то сломается или произойдет ошибка, то ничего в базе не изменится.
Спустя 5 минут, 53 секунды (27.01.2011 - 00:08) lovesa написал(а):
Цитата |
а альтернативы на русском случайно нет? |
по поводу альтернативы, как то в глаза не бросается простой текст на русском, как то везде сучковато описано.

Спустя 2 минуты, 54 секунды (27.01.2011 - 00:11) inpost написал(а):
lucasa
1. В int попадает число или значение? Если число, то применяй (int), а не mysql_real_escape_sting.
2. А почему может вдруг не обновиться вторая таблица? Какую именно причину ты видишь? Перегрузки сервера, что на середине скрипта вырубится?
1. В int попадает число или значение? Если число, то применяй (int), а не mysql_real_escape_sting.
2. А почему может вдруг не обновиться вторая таблица? Какую именно причину ты видишь? Перегрузки сервера, что на середине скрипта вырубится?
Спустя 6 секунд (27.01.2011 - 00:11) lucasa написал(а):
else
{
$createdDate = mysql_real_escape_string(gmdate($cfgFormat, time()));
mysql_query("INSERT INTO `result_user_view`(`resultid`,`email`,`result`,`status`,`date`)
VALUES('".mysql_real_escape_string($_POST['Id'])."','"
.mysql_real_escape_string($_SESSION['userlogin']).
"','".mysql_real_escape_string($_POST['Result'])."','1','".$createdDate."')");
if(mysql_affected_rows() == 1)
{
mysql_query("UPDATE `results` SET `total_results_count`='".($result['total_results_count']+1)."' WHERE `id`='".mysql_real_escape_string($result['id'])."'");
if(mysql_affected_rows() != 1)
{
$error = true;
}
else
{
$added = true;
}
}
else $error = true;
}
Здесь Insert если был, то обязательно должен быть UPDATE. Т.е. если UPDATE не прошел успешно, нужно делать DELETE Insertу...
И один из вопросов у меня был, можно ли как избежать этих многочисленных if'в?
Спустя 4 минуты, 54 секунды (27.01.2011 - 00:16) inpost написал(а):
вполне нормальная вложенность if-else. Не вижу смысла менять что-то.
Ты лучше объясни, чего именно ты боишься и хочешь добиться?
Ты лучше объясни, чего именно ты боишься и хочешь добиться?
Спустя 34 секунды (27.01.2011 - 00:16) lucasa написал(а):
inpost
сорри, малость не понимаю про какой int идет речь?
сорри, малость не понимаю про какой int идет речь?
Цитата |
1. В int попадает число или значение? Если число, то применяй (int), а не mysql_real_escape_sting. |
2. у меня знаний не хватает, чтобы судить о возможных проблемах...
как вариант что-то подвиснет...
как вариант сам INSERT INTO может не прокатить и до условия if(mysql_affected_rows() == 1) не дойдет очередь... но это мои преположения
Спустя 24 секунды (27.01.2011 - 00:17) lovesa написал(а):
Я думаю в данном случае тебе помогут транзакции и новая php конструкция исключений - exceptions: http://php.net/manual/en/language.exceptions.php.
работает это как то так: [code]
Но транзакции работают только на таблицах типа innodb
работает это как то так: [code]
try {
// начинаем транзакцию
$db->query('BEGIN');
// тут пошли запросы проверки и т.д
$db->query('first query');
$db->query('second query');
$db->query('third query');
// Если добрались до сюда, то подтверждаем изменения
$db->query('COMMIT');
} catch (Exception $e) {
//если была ошибка то
$db->query('ROLLBACK');
}
Но транзакции работают только на таблицах типа innodb
Спустя 2 минуты, 8 секунд (27.01.2011 - 00:19) lucasa написал(а):
inpost
я хотела бы избавиться от этих бесконечных проверок... тут даже assert не напишешь, т.к. просто так оборвать цепочку нельзя...
а боюсь, что что-то помешает выполнится транзакции целиком, т.е. целостность данных попортится...
я хотела бы избавиться от этих бесконечных проверок... тут даже assert не напишешь, т.к. просто так оборвать цепочку нельзя...
а боюсь, что что-то помешает выполнится транзакции целиком, т.е. целостность данных попортится...
Спустя 2 минуты, 52 секунды (27.01.2011 - 00:22) lucasa написал(а):
lovesa, спасибо, поизучаю!
у меня такого типа innodb - нет, даже не знаю, что это такое
у меня такого типа innodb - нет, даже не знаю, что это такое

Спустя 2 минуты, 30 секунд (27.01.2011 - 00:24) lovesa написал(а):
mysql по дефолту если я не ошибаюсь использует тип MyIsam если не ошибаюсь, но при помощи обыкновенного phpmyadmin можно поменять тип таблицы на innodb и спокойно делать rollback`и, если в этом если необходимость. Но тогда данных кусок кода придется немного модифицировать по мануалу exceptions
Спустя 1 минута, 43 секунды (27.01.2011 - 00:26) inpost написал(а):
Если запрос правильный, то врядли целостность будет повреждена.
ты получаешь $result['id'], в ней что содержится, порядковый номер (число) или текстовая строка? Мне кажется, что там число вроде 5, или 8, значит надо вставлять в таблицу так: .(int)$result['id'].
Пойми, пока нету такого, что твой сервер гнётся и хрустит от 10-и тысячного посетителя за последнюю секунду, то нет смысла думать о мелочных оптимизациях. Проверки проходят на первый взгляд логично и правильно, оставляй их такими.
И снова таки, целостность может повредиться только если в одну микросекунды вдруг сервер успеет выйти из строя, что будет врядли.
Просто если ты проектируешь и оптимизируешь сайт зарании известный, что он будет постоянно падать от перенагрузок - то стоит думать, если же обычный сайт, то можно даже не париться над оптимизацией и оставить таким, какой он есть.
ты получаешь $result['id'], в ней что содержится, порядковый номер (число) или текстовая строка? Мне кажется, что там число вроде 5, или 8, значит надо вставлять в таблицу так: .(int)$result['id'].
Пойми, пока нету такого, что твой сервер гнётся и хрустит от 10-и тысячного посетителя за последнюю секунду, то нет смысла думать о мелочных оптимизациях. Проверки проходят на первый взгляд логично и правильно, оставляй их такими.
И снова таки, целостность может повредиться только если в одну микросекунды вдруг сервер успеет выйти из строя, что будет врядли.
Просто если ты проектируешь и оптимизируешь сайт зарании известный, что он будет постоянно падать от перенагрузок - то стоит думать, если же обычный сайт, то можно даже не париться над оптимизацией и оставить таким, какой он есть.
Спустя 11 минут, 5 секунд (27.01.2011 - 00:37) lucasa написал(а):
inpost
да, порядковый индекс
(int)$result['id'] - а почему так лучше делать?
просто данные идут из формы, вроде как их лучше обезопасить...
сервер то будет не мой, хз как он будет работать)
в успешном варианте развития, запросов к сайту будет много практически одновременно, хотя сейчас мне это сложно оценить...
да, порядковый индекс
(int)$result['id'] - а почему так лучше делать?
просто данные идут из формы, вроде как их лучше обезопасить...
сервер то будет не мой, хз как он будет работать)
в успешном варианте развития, запросов к сайту будет много практически одновременно, хотя сейчас мне это сложно оценить...
Спустя 50 секунд (27.01.2011 - 00:38) lucasa написал(а):
lovesa, да, надо тогда будет почитать про эти таблицы
Спустя 28 минут, 34 секунды (27.01.2011 - 01:06) inpost написал(а):
lucasa
Потому что (int) - для числа, а string - для текстовой строки.
Потому что (int) - для числа, а string - для текстовой строки.
Спустя 9 часов, 38 минут, 50 секунд (27.01.2011 - 10:45) lucasa написал(а):
Меня тут сомнения стали одолевать. В примерах используется код:
а я стала использовать сравнение на точное количество обновленных строк:
а если в тоже самое время выполнится другой запрос, то эта функция может вернуть совсем иной результат...
как ей правильно пользоваться?
if(mysql_affected_rows() > 0)
а я стала использовать сравнение на точное количество обновленных строк:
if(mysql_affected_rows() == 1)
а если в тоже самое время выполнится другой запрос, то эта функция может вернуть совсем иной результат...
как ей правильно пользоваться?
Спустя 2 дня, 4 часа, 59 минут, 36 секунд (1.02.2011 - 15:45) lucasa написал(а):
подниму темку, интересует ответ на последний вопрос, хелп!
Спустя 4 дня, 6 часов, 42 минуты, 55 секунд (5.02.2011 - 22:28) lucasa написал(а):
lovesa
Цитата |
Но тогда данных кусок кода придется немного модифицировать по мануалу exceptions |
вы имели ввиду мой код или код вашего примера (в зависимости от типа таблицы)?