SELECT и UPDATE одновременно в многопотоке

  • Автор темы Автор темы Astraport
  • Дата начала Дата начала

Astraport

Client
Регистрация
01.05.2015
Сообщения
5 084
Реакции
4 633
Баллы
113
Есть таблица с кейвордами и ссылками. На каждый кейворд 30-50 ссылок.
Нужно забрать по заданному кейворду все ссылки, но при этом отметить, что они забраны.
Код:
Развернуть Свернуть Копировать
SELECT url FROM links WHERE post = '0' AND keywords = 'key';
UPDATE links SET post='1' WHERE keywords = 'key';
Но если в многопотоке, то возникают накладки, ключ берут сразу несколько потоков в паузе между запросами SELECT и UPDATE.
Советуют сделать по этому методу http://www.sqlines.com/mysql/how-to/select-update-single-statement-race-condition
но не врублюсь как мне переписать мои запросы?
 
Подпишусь. Как-то думал над этим, в итоге решил в 2 запроса всё равно.

По идее какой-то лок на уровне ZP надо бы юзать, т.к. транзакции не спасут
 
в мускуле есть свои локи
транзакции могут только хуже сделать в данном случае, т.к. залочив всю таблицу - где-то свалится исключение, хотя оно не желательно
 
транзакции могут только хуже сделать в данном случае, т.к. залочив всю таблицу - где-то свалится исключение, хотя оно не желательно
я говорил о локах, а не о транзакциях
 
не слышал о них, можно подробнее, применимо к текущему вопросу?


как в итоге выглядит в зенке?
ну ты даёшь запрос гет лок с именем лока и вроде максимальным временем жизни. Дальше твои запросы. Дальше освобождение лока. Насколько я понимаю, любой другой гет_лок с именем этого же лока будет ожидать освобождения
 
как в итоге выглядит в зенке?
Код:
Развернуть Свернуть Копировать
LOCK TABLES links WRITE;
SELECT url FROM links WHERE post = '0' AND keywords = '{-Variable.key-}';
UPDATE links SET post='1' WHERE keywords = '{-Variable.key-}';
UNLOCK TABLES;
 
  • Оценить
Реакции: nicanil, proffman и one
ну ты даёшь запрос гет лок с именем лока и вроде максимальным временем жизни. Дальше твои запросы. Дальше освобождение лока. Насколько я понимаю, любой другой гет_лок с именем этого же лока будет ожидать освобождения
Надо будет изучить этот вопрос, любопытно, спасибо)

@Astraport, мне так ещё было бы интересно запрос аля:
Код:
Развернуть Свернуть Копировать
SELECT id, url FROM links WHERE post = '0' AND keywords = '{-Variable.key-}';

Код:
Развернуть Свернуть Копировать
// тут C# код, который обработает url

Код:
Развернуть Свернуть Копировать
UPDATE links SET post='1' WHERE id = '{id}';

Т.е. между select и update иметь какую-то свою логику
 
Код:
Развернуть Свернуть Копировать
LOCK TABLES links WRITE;
SELECT url FROM links WHERE post = '0' AND keywords = '{-Variable.key-}';
UPDATE links SET post='1' WHERE keywords = '{-Variable.key-}';
UNLOCK TABLES;
А UPDATE успевает подхватывать то, что получает SELECT в переменной?
 
Я проверил у себя, нет, не подхватывает. Только если второй раз запустить экшен. Правда конструкция запросов немного другая.
 
Спасибо, попробую.
Странно, у меня все работает одним запросом.
Ну вот моя конструкция. UPDATE не выполняется с первого раза.

Код:
Развернуть Свернуть Копировать
SELECT `id`, `proxy_address` FROM `proxies` WHERE `proxy_status` = 0 ORDER BY `last_used_time` ASC;
UPDATE proxies SET `proxy_status` = 1, `last_used_time` = '{-TimeNow.TimeNow-}' WHERE `proxy_address` = '{-Variable.PROXY-}';
 
Странно, у меня все работает одним запросом.
В твоем случае все работает видимо потому что в переменной уже есть данные. А у меня SELECT получает в переменную а UPDATE использует из переменной.
 
А вот ещё такая задачка
Нужно сделать SELECT keywords FROM links WHERE post = '0';
но при этом взять, скажем, только 100 первых рядов удовлетворяющих условию post = '0' и из этих 100 взять только 1 случайный ряд.
И всё это одним запросом.
 
А вот ещё такая задачка
Нужно сделать SELECT keywords FROM links WHERE post = '0';
но при этом взять, скажем, только 100 первых рядов удовлетворяющих условию post = '0' и из этих 100 взять только 1 случайный ряд.
И всё это одним запросом.
Нужно делать запрос в запросе, что-то вроде:
SQL:
Развернуть Свернуть Копировать
SELECT * FROM (SELECT keywords FROM links WHERE post="0" ORDER BY `id` ASC LIMIT 0, 100) ORDER BY RAND() LIMIT 0,1
Но нужно потестировать производительность, сталкивался что из-за RAND в запросе - очень сильно падала скорость выборки
 
  • Оценить
Реакции: Astraport
Но нужно потестировать производительность, сталкивался что из-за RAND в запросе - очень сильно падала скорость выборки
Спасибо, проверю. Скорость особо не критична.
 
Подскажите как можно обновить несколько полей записи из файла.
Делаю так
LOAD DATA LOCAL INFILE "C:/ProgramData/MySQL/MySQL Server 5.7/Uploads/test.txt" REPLACE INTO TABLE table1
FIELDS TERMINATED BY '\t' ENCLOSED BY '' (col1, col2)
Меняются два поля а остальные (в моем случае еще 3) становятся NULL.
Пробовал
LOAD DATA LOCAL INFILE "C:/ProgramData/MySQL/MySQL Server 5.7/Uploads/test.txt" REPLACE INTO TABLE table1
FIELDS TERMINATED BY '\t' ENCLOSED BY '' (col1, col2) IGNORE (col3, col4, col5)
получается ошибка.
 
Попробовал выше метод лока в одном шаблоне. В принципе все ничего, одно но, потоки отваливаются не успев дождаться пока лок снимется. Конфиг MySQL надо править?
 
  1. Код:
    Развернуть Свернуть Копировать
    LOCK TABLES links WRITE;
    SELECT url FROM links WHERE post = '0' AND keywords = '{-Variable.key-}';
    UPDATE links SET post='1' WHERE keywords = '{-Variable.key-}';
    UNLOCK TABLES;

    Локается вся таблица?
    или только строки, с которыми связан запрос?
 

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