Этот баннер — требование Роскомнадзора для исполнения 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 |
|
||
|
|

start [/forum/topic.php?fid=23&msg=38939604&tid=1461829]: |
0ms |
get settings: |
9ms |
get forum list: |
11ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
74ms |
get topic data: |
6ms |
get forum data: |
3ms |
get page messages: |
37ms |
get tp. blocked users: |
1ms |
| others: | 234ms |
| total: | 379ms |

| 0 / 0 |
