powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Добавление строки при параллельных запросах
23 сообщений из 23, страница 1 из 1
Добавление строки при параллельных запросах
    #38925502
cybexx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.

Сходу задача кажется довольно банальная и, наверняка, обсуждалась много раз. Но я, к сожалению, не нашел решения. (Если плохо искал, пожалуйста, дайте конкретную ссылку)

Есть простая таблица

Код: sql
1.
2.
3.
4.
5.
CREATE TABLE IF NOT EXISTS `users` (
  `id` int(10) NOT NULL,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



Задача простая: проверить существование юзера с конкретным ID, если такой есть, то получить эту запись и продолжить с ним работать, Если нет то - создаем.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
SESSION1
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from users where id = 1 for update;
Empty set (0.00 sec)

SESSION2
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from users where id = 1 for update;
Empty set (0.00 sec)

SESSION1
mysql> insert into users (id,`name`) values(1,'Pit');
.... ожидание .... 

SESSION2
mysql> insert into users (id,`name`) values(1,'Pit');
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

SESSION1
Query OK, 1 row affected (9.85 sec)



В реальности задача, конечно же другая и более сложная. Для более легкого понимания, я убрал все лишнее и оставить только минимальные условия, которые вызывают конфликт.
Основные условия таковы: идентификатор задается в скрипте, между select-ом и insert-ом достаточно времени, чтобы мог появился параллельный запрос.
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38926663
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Переоформлю пример в виде таблички для наглядности
SESSION1SESSION2mysql> start transaction;Query OK, 0 rows affected (0.00 sec)mysql> select * from users where id = 1 for update;Empty set (0.00 sec)mysql> start transaction;Query OK, 0 rows affected (0.00 sec)mysql> select * from users where id = 1 for update;Empty set (0.00 sec)mysql> insert into users (id,`name`) values(1,'Pit');.... ожидание .... mysql> insert into users (id,`name`) values(1,'Pit');ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transactionQuery OK, 1 row affected (9.85 sec)
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38926675
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
За модельным примером (бессмысленным вообще до жути) потерялась собственно решаемая реально задача.
cybexxЗадача простая: проверить существование юзера с конкретным ID, если такой есть, то получить эту запись и продолжить с ним работать, Если нет то - создаем.
Если задача именно такова - то навылет непонятно, откуда лаг между проверкой наличия и вставкой при отсутствии. Вы явно что-то недоговариваете, причём важное. Возникают подозрения, что выбран в принципе неверный путь решения.
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38927775
cybexx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
Если вам не приходилось сталкиваться с такой задачей или вам трудно найти практическое применение задачи - вовсе не означает, что она "бессмысленная до жути"

Задача вполне реальная. Что в ней такого необычного, что вас смутило? Что id юзера задается во внешнем источнике?

Спасибо miksoft , что оформил в виде таблицы. Так действительно гораздо нагляднее.
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38927844
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cybexxЧто в ней такого необычного, что вас смутило?SELECT ... FOR UPDATE предназначен для SELECT, после которого будет выполнен именно UPDATE. У Вас после SELECT выполняется INSERT. Следовательно, у Вас неверен подход к решению задачи.

Я понимаю, что Вы выбрали какой-то путь решения задачи, и теперь, похоже, несмотря на его очевидную неправильность, будете с пеной у рта отстаивать его. Не советую - только зря время потеряете.
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38927993
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cybexx,

дык первым селектом (без for update) проверьте есть ли запись, а что дальше - это уже дальше... (уровень "изоляции" и т.д.)
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38928003
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cybexxAkina,
Если вам не приходилось сталкиваться с такой задачей или вам трудно найти практическое применение задачи - вовсе не означает, что она "бессмысленная до жути"

Я тоже согласен с идиотизмом задачи.

Но в принципе тебе сюда:
https://dev.mysql.com/doc/refman/5.0/en/lock-tables.html
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38928005
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38928010
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivSERIALIZABLEдык у него и так SERIALIZABLE, иначе откуда бы взяться дедлоку?
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38928045
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglirMasterZivSERIALIZABLEдык у него и так SERIALIZABLE, иначе откуда бы взяться дедлоку?

Дедлоков не должно быть на SERIALIZABLE ...
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38928704
cybexx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv,
Уровни изоляции стоят дефолтные.

Akina,
Я не собираюсь ничего доказывать и тем более с пеной у рта. У меня стоит задача, условия которые я привел еще в первом посте
Основные условия таковы: идентификатор задается в скрипте, между select-ом и insert-ом достаточно времени, чтобы мог появился параллельный запрос.
Я совсем не настаиваю, что мой вариант решения с SELECT FOR UPDATE идеальный, тем более я сам вижу что это дает ошибку. Просто другого варианта я пока не придумал, поэтому обратился на форум за помощью. Пока никто не предложил другого варианта. Предложите свое решение, буду благодарен.
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38928706
cybexx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv,
Уровни изоляции стоят дефолтные.

Akina,
Я не собираюсь ничего доказывать и тем более с пеной у рта. У меня стоит задача, условия которые я привел еще в первом посте
Основные условия таковы: идентификатор задается в скрипте, между select-ом и insert-ом достаточно времени, чтобы мог появился параллельный запрос.
Я совсем не настаиваю, что мой вариант решения с SELECT FOR UPDATE идеальный, тем более я сам вижу что это дает ошибку. Просто другого варианта я пока не придумал, поэтому обратился на форум за помощью. Пока никто не предложил другого варианта. Предложите свое решение, буду благодарен
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38928718
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cybexx,

чтение не блокирует на чтение, вот такая тофтология, поэтому вы эффекта от FOR UPDATE не получите.
FOR UPDATE просто "лочит" запись, чтобы ее никто не изменил. Вот так просто, если "на пальцах".
И только получив ошибку при UPDATE, вы сможете сказать пользователю - "запись уже редактируется"

т.е
1. Проверяете SELECT-ом c COUNT наличие записи
2. если нет - INSERT
3. если есть - следующая логика.
А того что вы хотите - оно вроде бы понятно, но в контексте - непонятно.
Опишите лучше так: "Два пользователя ..., один делает так-то..., другой..."
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38928726
cybexx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Уровни изоляции не помогают или я что-то не правильно делаю?

SESSION1SESSION2mysql> SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;Query OK 0 rows affected (0.00 sec)mysql> START TRANSACTION;Query OK 0 rows affected (0.00 sec)mysql> select * from users where id=1;Empty set (0.00 sec)mysql> SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;Query OK 0 rows affected (0.00 sec)mysql> START TRANSACTION;Query OK 0 rows affected (0.00 sec)mysql> select * from users where id=1;Empty set (0.00 sec)mysql> insert into users (id,`name`) values(1,'Pit');........mysql> insert into users (id,`name`) values(1,'Pit');ERROR 1213 (40001) Deadlock found when trying to get lock; try restarting transactionQuery OK 1 row affected (6.72 sec)
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38928738
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cybexxУровни изоляции не помогаютА чем вам тут сериалайз поможет? В первой транзакции болтается незакоммиченный ид=1, и пока она не определится, что с ним делать, вторая так и будет затыкаться...
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38928745
cybexx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
tanglir,
Просто выше в ветке упоминались уровни изоляции и что SERIALIZABLE не даст дедлоков.

Похоже, что только блокировка всей таблицы поможет решить задачу.
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38928759
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cybexxдругого варианта я пока не придумал, поэтому обратился на форум за помощью. Пока никто не предложил другого варианта. Предложите свое решение, буду благодаренА Вы не даёте возможности это сделать! Вместо формулирования задачи Вы формулируете свою попытку её решения. И всё, что мы можем - это указывать на кривость этой попытки.

Почему - сначала проверить, и только потом, если нет, вставить? Гораздо более очевидное решение - безусловно вставить (если запись уже есть - вставка не выполнится, уникальные индексы не дадут), а потом безусловно получить.
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38928896
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cybexx,

так опишите задачу, это при входе в систему пользователя? пытаетесь сделать авторегистрацию? или что?
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38928992
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot cybexx]MasterZiv,
Уровни изоляции стоят дефолтные.

Akina,
Я не собираюсь ничего доказывать и тем более с пеной у рта. У меня стоит задача, условия которые я привел еще в первом посте


так и решай свою задачу сам, чего ты сюда то пришел?
а не можешь -- придется доказывать.
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38929101
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cybexxtanglir,
Просто выше в ветке упоминались уровни изоляции и что SERIALIZABLE не даст дедлоков.

Похоже, что только блокировка всей таблицы поможет решить задачу.

Я предполагал, что SERIALIZABLE поможет, потому что по стандарту обязан.
Но я не уверен до конца, потому что я сам никогда не работал с SERIALIZABLE на MySQL.
SERIALIZABLE по идее и должен был бы блокировать таблицу целиком (или применять другие методы разрешения конфликтов, которые эквивалентны блокировке таблицы), но видимо он этого не делает.

Да, и ты бы мог применять генерацию новых ключей с помощью автоинкремента, а не в скрипте, автоматом проблем было бы меньше.

В том идиотизм твоей задачи и заключается -- ты в скрипте генерируешь идентификатор, и проверяешь наличие его в БД, а если нет --
именно с ним вставляешь запись, но вместе с тем имеешь конфликты. Значит, твой идентификатор несёт какую-то смысловую нагрузку из предметной области, а это недопустимо для идентификаторов, которые служат первичным ключём.

Твоя задача:
авторпроверить существование юзера с конкретным ID, если такой есть, то получить эту запись и продолжить с ним работать, Если нет то - создаем.

Ты должен был бы озаботиться проверкой существования пользователя с заданным логином, а не с заданным ID. ID ничего не значит, он должен работать только внутри системы.
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38929117
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivТы должен был бы озаботиться проверкой существования пользователя с заданным логином, а не с заданным ID. ID ничего не значит, он должен работать только внутри системы.Это, конечно, верно, но даже если заменить в постах ТСа "ид" на "логин", то в общем-то ничего не изменится - он точно так же будет натыкаться на дедлоки. Просто потому что работает так, как работает.
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38929172
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglirMasterZivТы должен был бы озаботиться проверкой существования пользователя с заданным логином, а не с заданным ID. ID ничего не значит, он должен работать только внутри системы.Это, конечно, верно, но даже если заменить в постах ТСа "ид" на "логин", то в общем-то ничего не изменится - он точно так же будет натыкаться на дедлоки. Просто потому что работает так, как работает.

Абсолютно согласен.
Но тогда автора топика бы не объявляли "странным" и, возможно, сразу бы дали ответ.
...
Рейтинг: 0 / 0
Добавление строки при параллельных запросах
    #38930177
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
есть еще именнованые псевдоблокировки, но это больше к раздельному Редактированию данных, как я понимаю.
Ф-и
GET_LOCK
RELEASE_LOCK
IS_FREE_LOCK
IS_USED_LOCK

как можно применить к вашему случаю - решать и знать вам.
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Добавление строки при параллельных запросах
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]