|
|
|
|
|
для: Valick
(30.09.2009 в 10:29)
| | Я понимаю Ваше желание как-то оправдаться и представить меня глупым человеком. Именно поэтому Вы решили проигнорировать мою новую, абсолютно чёткую формулировку, в посте от 30.09.2009 в 01:01. Хорошо, не можете найти решение - не надо, мне оно не требуется (оно требуется Вам, чтобы в дальнейшем не говорить лишнего). | |
|
|
|
|
|
|
|
для: Fractured#
(30.09.2009 в 01:01)
| | В MySQL предусмотрена возможность создания таблиц без транзакций, что необходимо приложениям, требующим максимально возможной скорости работы. Эти таблицы могут храниться в памяти, относиться к типу HEAP-таблиц или дисковых MyISAM.
Блокировка таблиц, применяющаяся в нетранзакционных таблицах MyISAM, во многих случаях работает быстрее, нежели блокировки на уровне страниц, строк или контроль версий. Недостаток этого подхода в том, что если не учитывать механизм работы блокирования таблиц, один длительный запрос может надолго заблокировать таблицу. Обычно этого эффекта можно избежать, приняв соответствующие меры при разработке приложения. Если это не удастся, всегда можно изменить тип таблицы и сделать ее транзакционной.
_____
http://www.mysql.ru/docs/man/
возможно информация несколько устарела, спорить не буду
_____
и ещё раз повторюсь, что понятия не имею что вы там творите, но для того чтобы вставить сообщение от бота в чат скорее всего вообще не нужна никакая блокировка таблиц...
погуглил по поводу не родного (!) для MySQL типа таблиц InnoDB сообщения похожи друг на друга как "диктанты первоклассников" что настораживает.
Но грубо говоря, если Вас устраивает полученный результат, то и дискутировать собсно не о чем. | |
|
|
|
|
|
|
|
для: Valick
(30.09.2009 в 00:12)
| | Ваш способ предполагает блокировку каждый раз, в противном случае это никак не поможет. И вообще, скажу Вам по секрету, InnoDB вообще-то при интенсивных запросах к таблице (SELECT/INSERT/DELETE/UPDATE) на нагруженных проектах предпочтительнее, нежели MyISAM.
MyISAM может блокировать только на уровне всей таблицы, а InnoDB - на уровне строк. Я как-то уже на эти грабли наступал, проект с очень большой посещаемость регулярно висел, в списках процессов были кучи запросов, ожидающих своей очереди к несчастной таблице MyISAM.
Если Вы до сих пор не понимаете в чём проблема, то самостоятельно смоделируйте ситуацию:
script1.php
<?php
$db->query('SELECT `timestamp` FROM ...');
if( $db->result() < time() )
{
sleep(25);
$db->query('UPDATE ... SET `timestamp` = ' . ( time() + 60 ));
$db->query('INSERT INTO test_table (page_num) VALUES(1)');
}
?>
|
script2.php
<?php
$db->query('SELECT `timestamp` FROM ...');
if( $db->result() < time() )
{
$db->query('UPDATE ... SET `timestamp` = ' . ( time() + 60 ));
$db->query('INSERT INTO test_table (page_num) VALUES(2)');
}
?>
|
Сначала запустите script1.php, затем script2.php. Задача состоит в том, чтобы в test_table оказалась лишь одна запись: 1
P.S.
Я надеюсь Вы не начнёте придираться к этому коду: это скорее псевдокод, просто показана логика. Оформите запросы, структуры таблиц как Ваша душа пожелает.
P.P.S. Да, про чат и ботов я зря, извиняюсь. Надо было сразу как-то абстрагироваться... | |
|
|
|
|
|
|
|
для: Fractured#
(29.09.2009 в 23:15)
| | модератор удалил вместе с Вашим постом мой последний дебильный совет, о том что блокировка (если она нужна, в чём лично я сильно сомневаюсь) раз в 5 минут - это лучше, чем ежесекундный проигрышь в скорости при использовании InnoDB (тем более что у вас такой нагруженный чат) | |
|
|
|
|
|
|
|
для: Valick
(29.09.2009 в 18:04)
| | Выражусь культурнее: спасибо, мне не нужна блокировка всей таблицы сразу. | |
|
|
|
|
|
|
|
для: Fractured#
(29.09.2009 в 17:36)
| | InnoDB медленнее MyISAM
Транзакции нужны грубо говоря из-за возможности отката, что вы собираетесь откатывать в чате?
Того же можно добиться с помощью блокировки таблиц, хотя нужна она тут или нет я сказать не возьмусь, уж очень непонятно вы всё обьяснили.
Вы случайно не WoW ковыряете? | |
|
|
|
|
|
|
|
для: Fractured#
(27.09.2009 в 23:28)
| | Всё-таки решается по-нормальному средствами MySQL (тип таблицы - InnoDB):
<?php
mysql_query('SET `autocommit` = 0;');
mysql_query('START TRANSACTION;');
mysql_query('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;');
mysql_query('SELECT `last_posting_date` FROM ... FOR UPDATE');
if( time() - $last_posting_date > 300 )
{
mysql_query('UPDATE ... SET `last_posting_date` = ' . time() . ';');
# Добавление поста и т.д.
}
mysql_query('COMMIT;');
?>
|
| |
|
|
|
|
|
|
|
для: Trianon
(27.09.2009 в 23:27)
| | В Вашем - да. Просто он не очень нравится... OK, я ещё поищу другие способы. | |
|
|
|
|
|
|
|
для: Fractured#
(27.09.2009 в 23:14)
| | в моем варианте я не вижу никакого перезатирания .
в вапранте а-я, очевидно, слегка придется доточить логику. | |
|
|
|
|
|
|
|
для: Trianon
(22.08.2009 в 00:22)
| | Вновь возвращаюсь к этой теме :confused:
Такой ход не подходит. Я не совсем раскрыл суть проблемы.
Бот задаёт какой-то вопрос. Пользователи отвечают. Иногда он задаёт подряд 2 вопроса. И всё это очень походит на борьбу со следствием, а не причиной. Причём Ваш вариант тоже, если честно...
Т.е. причина: начинается смена стадии этой викторины (стадий несколько: инициализация вопроса, подсказка, завершение в случае истечения времени) параллельно в 2-х скриптах. race condition...
По совету а-я получится так: бот задаст какой-то вопрос (т.е. идентификатор вопроса сохранится в определенном месте), он появится в чате. Но другой скрипт перезатрёт идентификатор вопроса, но в чате новый вопрос не появится. | |
|
|
|
|