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

Gor

Client
Регистрация
30.09.2016
Сообщения
250
Реакции
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/thre...roku-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. Выполнить запрос удаления строки из БД.
Как это сделать?
Весь день просидел, ни к чему не пришел. Помогите пожалуйста!
 
Последнее редактирование:
У меня так, в многопотоке дубли при взятии не встречаются
Код:
Развернуть Свернуть Копировать
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;
Спасибо дружище!!! Сейчас буду тестить! Кажется, это то, что нужно!
Только я уже немного почитал по поводу блокировок и я вижу на понятийном уровне, что у тебя блокируется на запись вся таблица - она до завершения текущей транзакции не может быть изменена. Мне же нужно поставить блокировку на чтение строку, которая считывается а затем удаляется текущей транзакцией. Если это сделать у нас по идее скорость шуба вырастет многократно.
 
Последнее редактирование:
Спасибо дружище!!! Сейчас буду тестить! Кажется, это то, что нужно!
Только я уже немного почитал по поводу блокировок и я вижу на понятийном уровне, что у тебя блокируется на запись вся таблица - она до завершения текущей транзакции не может быть изменена. Мне же нужно поставить блокировку на чтение строку, которая считывается а затем удаляется текущей транзакцией. Если это сделать у нас по идее скорость шуба вырастет многократно.
Вот здесь думаю найдете свой ответ:
 
У меня так, в многопотоке дубли при взятии не встречаются
Код:
Развернуть Свернуть Копировать
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;
А можно сделать так, чтобы бралась, а затем удалялась рандомная строка?
 
Решается в 2 шага
1.Въехать в уровни изоляции транзакций
2. Проще в виде хранимой процедуры, завернуть в одну транзакцию 2 запроса. Первый получает данные, второй удаляет строку, ну и процедура возвращает полученные данные.
 
У меня так, в многопотоке дубли при взятии не встречаются
Код:
Развернуть Свернуть Копировать
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;
Народ выручайте, как на таблицу переделать, или в дефолтном кубике локать? Нужно брать результат в таблицу и удалять строку. Ай нид хелп? весь инет облазил, рандом или через каунт строк не вариант, очень проц грузит.
 
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
 
У меня так, в многопотоке дубли при взятии не встречаются
Код:
Развернуть Свернуть Копировать
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;
Привет! Разве данный запрос не удалит любую другую строку? как он понимает какую строку удалить?
 

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