Извлечь строку из таблицы БД MySQL с удалением одним запросом стандартными средствами Зеннопостер

Gor

Client
Регистрация
30.09.2016
Сообщения
248
Благодарностей
30
Баллы
28
Привет, ребята! Может быть кто-то знает как извлечь строку из таблицы БД MySQL с удалением одним запросом стандартными средствами Зеннопостер? Написал парсер, он берет строку из БД одним запросом (стандартным кубиком), вторым запросом удаляет. Если запускаю в многопотоке, образуется множество дублей. Как с этим бороться, может быть кто подскажет? Если нет возможности сделать это стандартными средствами, подскажите как сделать это с применением С#.
т.е. мне нужно выполнить два элементарных запроса к БД:
SELECT * from table limit 1 и записать его в переменную. Желательно иметь возможность записать в несколько переменных если будет несколько колонок.
DELETE from table LIMIT 1

Мне подсказали, что есть 3 варианта:

вариант раз: локи на уровне шаба (Говорят нужно использовать код вида:
Код:
CommonCode.SyncObject){
//тут работа с бд берем запись и удаляем если надо
}
Моя твоя не понимайт! Куда его вставлять? В using? В C#? Там, где записано "//тут работа с бд берем запись и удаляем если надо" надо написать запрос к БД вида "SELECT * from table limit 1; DELETE from table LIMIT 1"?

вариант два: локи на уровне бд
Нужно испоьлзовать запросы вида START TRANSACTION; ... COMMIT; ?
У меня запрос на извлечение строки из БД делается одним кубиком, запрос на удаление этой строки - вторым кубиком. Для лока на уровне БД нужно впихнуть каким-то образом два запроса в один кубик? Например на C#?.. Но я в C# откровенно говоря не силен ((

вариант три: локи на уровне хранимой процедуры
Нашел решение тут http://zennolab.com/discussion/threads/mysql-vzjat-unikalnuju-stroku-i-obnovit-tranzakcija.36704/#post-335529
Моя его интерпретация сельского Вани:
1. на сервере БД MySQL - хранимая процедура.
Код:
PROCEDURE ok_database.accnt_id()
  MODIFIES SQL DATA
BEGIN
  set @rid = -1;
  START TRANSACTION;
  SELECT * INTO @rid from table limit 1
  DELETE from table LIMIT 1
  SELECT @rid;
  COMMIT;
END
Вопрос в том верна ли она и куда эту процедуру вставлять в MySQL.
2. В Zennoposter - два кубика.
C#
Код:
string query = "call ok_database.accoutn_id();";
string res = ZennoPoster.Db.ExecuteScalar(query,null,ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient,
                                        project.Variables["MySQLConnectString"].Value);
                                      
return res;
project.Variables["MySQLConnectString"].Value - что должно находится в этой переменной?

3. И кубик работы с БД
Зачем нужен кубир работы с БД, если мы прописали хранимую процедуру в БД? Она разве не является запросом?



Т.е. на понятийном уровне нужно:
1. Выполнить запрос взятия строки из таблицы БД и одновременно залочить строку, над которой работаю для других потоков.
2. Выполнить запрос удаления строки из БД.
Как это сделать?
Весь день просидел, ни к чему не пришел. Помогите пожалуйста!
 
Последнее редактирование:

SoUp1

Client
Регистрация
15.09.2013
Сообщения
145
Благодарностей
47
Баллы
28
У меня так, в многопотоке дубли при взятии не встречаются
Код:
string zapros = @"LOCK TABLES nametable WRITE;
         SELECT * FROM nametable LIMIT 1;
         DELETE FROM nametable LIMIT 1;
         UNLOCK TABLES;";

string rezult = ZennoPoster.Db.ExecuteQuery(zapros, null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, "server=localhost;user id=root;database=base", " ", "");
return rezult;
 
Последнее редактирование:

Gor

Client
Регистрация
30.09.2016
Сообщения
248
Благодарностей
30
Баллы
28
У меня так, в многопотоке дубли при взятии не встречаются
Код:
string zapros = @"LOCK TABLES nametable WRITE;
         SELECT * FROM nametable LIMIT 1;
         DELETE FROM nametable LIMIT 1;
         UNLOCK TABLES;";

string rezult = ZennoPoster.Db.ExecuteQuery(zapros, null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, "server=localhost;user id=root;database=base", " ", "");
return rezult;
Спасибо дружище!!! Сейчас буду тестить! Кажется, это то, что нужно!
Только я уже немного почитал по поводу блокировок и я вижу на понятийном уровне, что у тебя блокируется на запись вся таблица - она до завершения текущей транзакции не может быть изменена. Мне же нужно поставить блокировку на чтение строку, которая считывается а затем удаляется текущей транзакцией. Если это сделать у нас по идее скорость шуба вырастет многократно.
 
Последнее редактирование:

takerz

Client
Регистрация
02.07.2016
Сообщения
179
Благодарностей
23
Баллы
18
Спасибо дружище!!! Сейчас буду тестить! Кажется, это то, что нужно!
Только я уже немного почитал по поводу блокировок и я вижу на понятийном уровне, что у тебя блокируется на запись вся таблица - она до завершения текущей транзакции не может быть изменена. Мне же нужно поставить блокировку на чтение строку, которая считывается а затем удаляется текущей транзакцией. Если это сделать у нас по идее скорость шуба вырастет многократно.
Вот здесь думаю найдете свой ответ:
 

Atlas

Client
Регистрация
16.02.2014
Сообщения
131
Благодарностей
8
Баллы
18
У меня так, в многопотоке дубли при взятии не встречаются
Код:
string zapros = @"LOCK TABLES nametable WRITE;
         SELECT * FROM nametable LIMIT 1;
         DELETE FROM nametable LIMIT 1;
         UNLOCK TABLES;";

string rezult = ZennoPoster.Db.ExecuteQuery(zapros, null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, "server=localhost;user id=root;database=base", " ", "");
return rezult;
У меня так, в многопотоке дубли при взятии не встречаются
Код:
string zapros = @"LOCK TABLES nametable WRITE;
         SELECT * FROM nametable LIMIT 1;
         DELETE FROM nametable LIMIT 1;
         UNLOCK TABLES;";

string rezult = ZennoPoster.Db.ExecuteQuery(zapros, null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, "server=localhost;user id=root;database=base", " ", "");
return rezult;
А можно сделать так, чтобы бралась, а затем удалялась рандомная строка?
 

uuw

Client
Регистрация
04.06.2020
Сообщения
146
Благодарностей
54
Баллы
28
Решается в 2 шага
1.Въехать в уровни изоляции транзакций
2. Проще в виде хранимой процедуры, завернуть в одну транзакцию 2 запроса. Первый получает данные, второй удаляет строку, ну и процедура возвращает полученные данные.
 

Wide

Client
Регистрация
04.02.2013
Сообщения
945
Благодарностей
257
Баллы
63

Wide

Client
Регистрация
04.02.2013
Сообщения
945
Благодарностей
257
Баллы
63
У меня так, в многопотоке дубли при взятии не встречаются
Код:
string zapros = @"LOCK TABLES nametable WRITE;
         SELECT * FROM nametable LIMIT 1;
         DELETE FROM nametable LIMIT 1;
         UNLOCK TABLES;";

string rezult = ZennoPoster.Db.ExecuteQuery(zapros, null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, "server=localhost;user id=root;database=base", " ", "");
return rezult;
Народ выручайте, как на таблицу переделать, или в дефолтном кубике локать? Нужно брать результат в таблицу и удалять строку. Ай нид хелп? весь инет облазил, рандом или через каунт строк не вариант, очень проц грузит.
 

legorange

Client
Регистрация
22.04.2020
Сообщения
13
Благодарностей
34
Баллы
13
Mysql like works queue,
Multiple queries at the same time

SQL:
BEGIN;
SET @v1 = (
SELECT id_table FROM my_table WHERE task_done = 0 LIMIT 1 FOR UPDATE);
DELETE FROM my_table WHERE id_table = @v1;
Select @v1;
COMMIT;
remember "semicolon" behind each mysql line

The query returns the id to work, once obtained and blocked, do. . .

Tables: InnoDB
Mysql: 5.7

Connection String must included: allowuservariables=True


86971
 

Gfoblin

Client
Регистрация
30.05.2013
Сообщения
4 594
Благодарностей
1 014
Баллы
113

Wide

Client
Регистрация
04.02.2013
Сообщения
945
Благодарностей
257
Баллы
63

TheBoss

Client
Регистрация
30.03.2015
Сообщения
529
Благодарностей
194
Баллы
43
У меня так, в многопотоке дубли при взятии не встречаются
Код:
string zapros = @"LOCK TABLES nametable WRITE;
         SELECT * FROM nametable LIMIT 1;
         DELETE FROM nametable LIMIT 1;
         UNLOCK TABLES;";

string rezult = ZennoPoster.Db.ExecuteQuery(zapros, null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, "server=localhost;user id=root;database=base", " ", "");
return rezult;
Привет! Разве данный запрос не удалит любую другую строку? как он понимает какую строку удалить?
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)