Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
Здравствуйте, прошу помощи... В общем есть функция создающая новый ID соответствующий минимальному несуществующему. function newPhonesGroup() { $minId = mysql_result(mysql_query("SELECT MIN(NULLIF(R1.groupid + 1, R2.groupid)) as mid FROM (SELECT groupid FROM phonesgroup UNION SELECT 0) R1 LEFT OUTER JOIN phonesgroup R2 ON R2.groupid = (R1.groupid + 1) OR R2.groupid IS NULL"),0,'mid'); mysql_query("insert into phonesgroup(groupid,cdate)values($minId,'".date('Y-m-d [H:i:s]')."')"); return $minId; } Первый запрос ищет минимальный ID из несуществующих в таблице phonesgroup, второй записывает его в эту таблицу. Но сейчас стали возникать проблемы, при одновременном вызове функции из разных скриптов, она может вернуть один и тот же ID обоим... Скорее всего это происходит когда первый запрос выполняется одновременно, до записи(во втором запросе). Как можно этого избежать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2015, 16:13 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
hated, присваивать ID при инсерте, не использовать конструкции вида +1, autoincrement ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2015, 16:28 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
Но мне нужен минимальный из пустых ID как это сделать? Иначе у меня каждый месяц айдишники кончаться будут) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2015, 16:55 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
hated, не вызывать функцию из разных скриптов :) заморачиваться с блокировками в хранимке уникальность по полю+завернуть в транзакцию, при получении ошибки перевыбрать номер ну и тому подобную чушь :) часто оказывается нахождение пропусков пропусков в нумерации не такая необходимая вещь, и тешит только глаз программиста, когда смотришь на эти красивые подряд идущие циферки :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2015, 17:13 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
hatedНо мне нужен минимальный из пустых ID как это сделать? Иначе у меня каждый месяц айдишники кончаться будут) Значит не пользуйся суррогатными ключами. Используй естественный ключ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2015, 17:13 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
да ещё видела маразм генерировать табличку с диапазоном номеров и делать к ней привязку - нет привязки -> свободная касса ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2015, 17:15 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
Как думаете если после второго запроса добавить рекурсию if (!mysql_affected_rows()) return newPhonesGroup(); Это решит проблему? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.04.2015, 17:20 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
hatedНо мне нужен минимальный из пустых ID как это сделать? Иначе у меня каждый месяц айдишники кончаться будут)Если у вас будет столько записей, что "айдишники кончаться будут", то первый запрос у вас будет час выполняться ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.04.2015, 05:21 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
?hatedНо мне нужен минимальный из пустых ID как это сделать? Иначе у меня каждый месяц айдишники кончаться будут)Если у вас будет столько записей, что "айдишники кончаться будут", то первый запрос у вас будет час выполняться Дак в том то и дело что непрерывно одни айдишники удаляюся(освобождаются) другие добавляются(берут освободившиеся айди). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.04.2015, 11:06 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
hated?пропущено... Если у вас будет столько записей, что "айдишники кончаться будут", то первый запрос у вас будет час выполняться Дак в том то и дело что непрерывно одни айдишники удаляюся(освобождаются) другие добавляются(берут освободившиеся айди).Ну если генерировать по одному id в секунду, int переполнится через больше чем 60 лет. А если взять bigint, то можно по миллиону id в секунду выдавать в течении ста тысяч лет... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.04.2015, 12:41 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
hatedКак думаете если после второго запроса добавить рекурсию if (!mysql_affected_rows()) return newPhonesGroup(); Это решит проблему? НЕ ПОМОГЛО =( Сегодня опять обнаржил косяк... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2015, 15:12 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
hated, поле в базе уникальное? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2015, 15:50 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
В общем поступил радикально: 1) Перевел эту таблицу из MyISAM в InnoDB; 2) Сделал блокировку mysql_query("LOCK TABLES phonesgroup WRITE"); ......... mysql_query("UNLOCK TABLES"); Кто подскажет, поможет ли это и какие могут быть побочки? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2015, 15:58 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
-k2-hated, поле в базе уникальное? Да - а толку... Функция должна генерировать и записывать в phonesgroup уникальный groupid. Но нет-нет вижу случаи когда при работе в одно и то же время она отдает разным потокам один и тот же... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2015, 16:00 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
hated, а где у вас проверка на код возврата mysql_query("insert into phonesgroup(groupid,cdate)values($minId,'".date('Y-m-d [H:i:s]')."')"); ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2015, 16:03 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
-k2-hated, а где у вас проверка на код возврата mysql_query("insert into phonesgroup(groupid,cdate)values($minId,'".date('Y-m-d [H:i:s]')."')"); ? Не совсем вас понял... Вы о чём? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2015, 16:13 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
Чет я совсем запутался так вообще работать не хочет возвращает пустое значение: function newPhonesGroup() { mysql_query("LOCK TABLES phonesgroup WRITE"); $minId = mysql_result(mysql_query("SELECT MIN(NULLIF(R1.groupid + 1, R2.groupid)) as mid FROM (SELECT groupid FROM phonesgroup UNION SELECT 0) R1 LEFT OUTER JOIN phonesgroup R2 ON R2.groupid = (R1.groupid + 1) OR R2.groupid IS NULL"),0,'mid'); mysql_query("insert into phonesgroup(groupid,cdate)values($minId,'".date('Y-m-d [H:i:s]')."')"); mysql_query("UNLOCK TABLES"); return $minId; } Как сделать так, чтобы пока работает эта функция все остальные потоки пытающиеся её запустить - ожидали её окончания? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2015, 16:30 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
hated, mysql_query возвращает результат: true - если ваш групид ставлен, false - если ваш групид не вставлен (например неуникален) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2015, 16:33 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
-k2-hated, mysql_query возвращает результат: true - если ваш групид ставлен, false - если ваш групид не вставлен (например неуникален) Хм - стыдно... Я об этом не подумал начал mysql_affected_rows для этого юзать... Ладно пусть тогда сейчас так поработает: function newPhonesGroup() { $minId = mysql_result(mysql_query("SELECT MIN(NULLIF(R1.groupid + 1, R2.groupid)) as mid FROM (SELECT groupid FROM phonesgroup UNION SELECT 0) R1 LEFT OUTER JOIN phonesgroup R2 ON R2.groupid = (R1.groupid + 1) OR R2.groupid IS NULL"),0,'mid'); if (!$minId || !mysql_query("insert into phonesgroup(groupid,cdate)values($minId,'".date('Y-m-d [H:i:s]')."')")) { sleep(1); return newPhonesGroup(); } return $minId; } Может в сумме с InnoDB - косяки пропадут... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2015, 16:44 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
по задаче: пусть Id: 1, 2, 3, NULL, 147, 148, NULL, 150, 151 твоя функция должна вернуть 4 так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.04.2015, 18:36 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
mini.weblabпо задаче: пусть Id: 1, 2, 3, NULL, 147, 148, NULL, 150, 151 твоя функция должна вернуть 4 так? ну да... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2015, 07:44 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
hated, 1) Если используешь локи на таблицы, то на InnoDB переходить не нужно 2) Это твоя база? Ты имеешь право таблицы лочить? 3) советую проверить успешность выполнение запросов примерно так: $res = mysql_query($some_query); if(!res) die ("Database access failed: " . mysql_error()); или менее сурово: if(!res) echo ("Database access failed: " . mysql_error()); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2015, 15:24 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
mini.weblab, поправка $res = mysql_query($some_query); if(!$res) die ("Database access failed: " . mysql_error()); или менее сурово: if(!$res) echo ("Database access failed: " . mysql_error()); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2015, 15:25 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
hated?пропущено... Если у вас будет столько записей, что "айдишники кончаться будут", то первый запрос у вас будет час выполняться Дак в том то и дело что непрерывно одни айдишники удаляюся(освобождаются) другие добавляются(берут освободившиеся айди). сколько в сутки? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.04.2015, 21:48 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
ответ был в самом первом посте. только вместо селескт трали-вали инсерт инту табле селект-траливали тоесть выборка и тутже вставка. паралельный изза уникальности поля(оно должно быть) уже выдаст ошибку, и тогда да повторно вставить. насчёт того что один запрос будет выполняться час... ну формально, если бросать монетку (решка - выполниться первее другого, орёл - после) то шанс есть что 10000 раз выпадет решка. но с таким шансом и даже большим, у вас куча багов и ошибок на проекте. а с другой стороны, если запросов столько что реальный шанс что какойто будет выполняться час, то вопрос - а вообще рационально из таблицы где за месяц айдишники заканчиваються(настолько нагруженная с ней работа) постоянно выборку минимального значения делать? ======== зы я бы не так делал, и начал бы с абсурдности поиска минимального айди. абсурдности. 1)мы нашли минимальный 10, потенциальная проблема, что другой запрос тоже найдёт минимальный 10, вместо 11 - тогда возникает вопрос, разве не было бы решением если второй искал бы сразу не минимальное а 11. это явно автора устраивает, соответсвенно вопрос - так зачем мы исчём именно минимальное, а не просто любое значение которого нету? 2)вариант заканчивающегося за месяц айди, на фоне ГРУППЫ номеров(даже не номера) и максимальным значением 64битного числа представляеться абсурдом, особенно если учесть что можно брать ГУИД или подобное...128 битные значения, можно 256 битные значения. не надо переживать изза возростающей нагрузки- костыли и руки из сопы куда более нагрузят базу. 3) сам запрос...он довольно таки тяжёллый. он вообще сколько времени на этой таблице выполняеться 4)каково назначение этого поля и записи в целом...почему вообще так получаеться, что на платёжных системах транкзанкции...даже на мировых системах, и айдишники для транкзанкций не заканчиваються, а у тебя для групы номеров заканчиваються(вот я пользуюсь системой где можно купить номер телефонный из группы, и на такую покупку есть транкзанкция....транкзанкций точно больше чем номеров груп, но у них не заканчиються) (что-то мне кажеться, что это фанстическое предположение автора, что у него закончаться айди) ======== и для тех кто боится что в случае лока можно на долго зависнуть. при любых локах есть шанс долго подвисания, даже в случае очереди - она может большой оказаться. ТАК ЧТО автору надо менять изначальный подход с этими минимальными айди. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.04.2015, 17:18 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
alex564657498765453зы я бы не так делал, и начал бы с абсурдности поиска минимального айди. абсурдности. 1)мы нашли минимальный 10, потенциальная проблема, что другой запрос тоже найдёт минимальный 10, вместо 11 - тогда возникает вопрос, разве не было бы решением если второй искал бы сразу не минимальное а 11. это явно автора устраивает, соответсвенно вопрос - так зачем мы исчём именно минимальное, а не просто любое значение которого нету? а я бы посмотрела a) на код где вы находите 11-й отсутствующий ID б) на код где вы находите произвольный отсутствующий ID с) давайте предполагать, что автор использовал SMALLINT для ID =) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.04.2015, 17:49 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
mini.weblabalex564657498765453зы я бы не так делал, и начал бы с абсурдности поиска минимального айди. абсурдности. 1)мы нашли минимальный 10, потенциальная проблема, что другой запрос тоже найдёт минимальный 10, вместо 11 - тогда возникает вопрос, разве не было бы решением если второй искал бы сразу не минимальное а 11. это явно автора устраивает, соответсвенно вопрос - так зачем мы исчём именно минимальное, а не просто любое значение которого нету? а я бы посмотрела a) на код где вы находите 11-й отсутствующий ID б) на код где вы находите произвольный отсутствующий ID с) давайте предполагать, что автор использовал SMALLINT для ID =) с)и что, религия запрещает перейти на другой тип? б)как два пальца об асфальт.даже без джоина,...сдесь на форуме уже были даже готовые примеры через переменные а)вы не поняли мысли.... зачем акцент на минимальном айди, и как пример, второй процес сразу взял себе 11, а первый 10 потом- они искали не минимальный...но суммарный эффект как будто бы минимальный - явно не противоречит ТС, а следовательно - требования а минимальности не обязательное условия для решения задачи. ... это догматично показал на пальцах, что минимальность сдесь не нужна(ну либо ТС плохо описал что у него там проиходит) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.04.2015, 08:23 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
О! Оживление =) В общем, не буду привязываться к цитатам отвечу в общем. Да скорее всего я и погорячился - может не месяц, может даже не два и не год. Но!!! Это еще хуже, сейчас я знаю об этом узком месте и пытаюсь его оптимизировать, но забей я на это - в один прекрасный момент получаю баг, потери времени на исправление, потере на возмещение убытков простоя и т.д. Сейчас у нас 8 едентичных баз(разные города), кто знает сколько их будет через год-два... И уж тем более потом угадай в какой базе кончатся айдишники... Зачем эта бомба замедленного действия если вполне можно обойтись и без неё?... Не отрицаю существование способов реализации более правильных и менее косячных и ресурсоемких. Но!!! Эта функция работает с 2011го года и косяки выявились только сейчас(и то редкие и не значительные), по нагрузке/времени работы нареканий нет... По этому смысла менять принцип работы и рисковать появлениями других багов(в случае если что-то забыл/не учел), лично я не вижу... Итого: От блокировок решил отказаться - побоялся и сделал как описал выше - перевел в Inno и делаю рекурсию если не произошла вставка. function newPhonesGroup() { $minId = mysql_result(mysql_query("SELECT MIN(NULLIF(R1.groupid + 1, R2.groupid)) as mid FROM (SELECT groupid FROM phonesgroup UNION SELECT 0) R1 LEFT OUTER JOIN phonesgroup R2 ON R2.groupid = (R1.groupid + 1) OR R2.groupid IS NULL"),0,'mid'); if (!$minId || !mysql_query("insert into phonesgroup(groupid,cdate)values($minId,'".date('Y-m-d [H:i:s]')."')")) { sleep(1); return newPhonesGroup(); } return $minId; } Пока косяков не выявлено - как будут - обещаю Вас поставить в известность и быть более внимательным к вашим советам! =) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.04.2015, 09:53 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
hatedО! Оживление =) В общем, не буду привязываться к цитатам отвечу в общем. Да скорее всего я и погорячился - может не месяц, может даже не два и не год. Но!!! Это еще хуже, сейчас я знаю об этом узком месте и пытаюсь его оптимизировать, но забей я на это - в один прекрасный момент получаю баг, потери времени на исправление, потере на возмещение убытков простоя и т.д. Сейчас у нас 8 едентичных баз(разные города), кто знает сколько их будет через год-два... И уж тем более потом угадай в какой базе кончатся айдишники... Зачем эта бомба замедленного действия если вполне можно обойтись и без неё?... Не отрицаю существование способов реализации более правильных и менее косячных и ресурсоемких. Но!!! Эта функция работает с 2011го года и косяки выявились только сейчас(и то редкие и не значительные), по нагрузке/времени работы нареканий нет... По этому смысла менять принцип работы и рисковать появлениями других багов(в случае если что-то забыл/не учел), лично я не вижу... Итого: От блокировок решил отказаться - побоялся и сделал как описал выше - перевел в Inno и делаю рекурсию если не произошла вставка. function newPhonesGroup() { $minId = mysql_result(mysql_query("SELECT MIN(NULLIF(R1.groupid + 1, R2.groupid)) as mid FROM (SELECT groupid FROM phonesgroup UNION SELECT 0) R1 LEFT OUTER JOIN phonesgroup R2 ON R2.groupid = (R1.groupid + 1) OR R2.groupid IS NULL"),0,'mid'); if (!$minId || !mysql_query("insert into phonesgroup(groupid,cdate)values($minId,'".date('Y-m-d [H:i:s]')."')")) { sleep(1); return newPhonesGroup(); } return $minId; } Пока косяков не выявлено - как будут - обещаю Вас поставить в известность и быть более внимательным к вашим советам! =) дык что косяков пока не было?! Будут! пышли студент. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.04.2015, 10:02 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
alex564657498765453дык что косяков пока не было?! Будут! пышли студент. Сплюньте! Ну их нафиг... =) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.04.2015, 11:27 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
alex564657498765453, alex564657498765453 с)и что, религия запрещает перейти на другой тип? ну, во-первых, в общем-то да, запрещает, особенно если не знаешь, кто, как и для чего еще использует базу во вторых, с ограничениями интересней, а SMALLINT я просто так предположила, надо же с чего-то начать =) alex564657498765453 а)вы не поняли мысли.... зачем акцент на минимальном айди, и как пример, второй процес сразу взял себе 11, а первый 10 потом- они искали не минимальный...но ну может и не поняла, просто минимальный/максимальный найти легче (имхо). поэтому было бы интересно посмотреть, как можно найти 11-й, 125-й alex564657498765453 б)как два пальца об асфальт.даже без джоина,...сдесь на форуме уже были даже готовые примеры через переменные ну вот я и говорю, что было бы интересно посмотреть код. тем более, что для вас это настолько просто ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.04.2015, 12:00 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
hated, используй mysqli =) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.04.2015, 12:03 |
|
||
|
Запрет одновременного выполнения
|
|||
|---|---|---|---|
|
#18+
hatedЗачем эта бомба замедленного действия если вполне можно обойтись и без неё?... как раз текущая реализация -- бомба. то, что скрипт работает с 2011 года не показатель. в случае проблем тщательно скрывай свой адрес от тех, кто будет поддерживать систему после тебя. ты занимаешься хренью, а не оптимизацией, меняй эту кривизну пока не поздно ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.04.2015, 15:15 |
|
||
|
|

start [/forum/topic.php?all=1&fid=23&tid=1461829]: |
0ms |
get settings: |
9ms |
get forum list: |
21ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
70ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
87ms |
get tp. blocked users: |
2ms |
| others: | 231ms |
| total: | 443ms |

| 0 / 0 |
