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

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 941
Благодарностей
4 331
Баллы
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
но не врублюсь как мне переписать мои запросы?
 

Lord_Alfred

Client
Регистрация
09.10.2015
Сообщения
3 916
Благодарностей
3 852
Баллы
113
Подпишусь. Как-то думал над этим, в итоге решил в 2 запроса всё равно.

По идее какой-то лок на уровне ZP надо бы юзать, т.к. транзакции не спасут
 

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 941
Благодарностей
4 331
Баллы
113
@Lord_Alfred
Я ссылочку дал, рекомендуют как решение. Но там не совсем то, что мне нужно.
 

Lord_Alfred

Client
Регистрация
09.10.2015
Сообщения
3 916
Благодарностей
3 852
Баллы
113

doc

Client
Регистрация
30.03.2012
Сообщения
8 605
Благодарностей
4 595
Баллы
113
в мускуле есть свои локи
 
  • Спасибо
Реакции: Astraport

Lord_Alfred

Client
Регистрация
09.10.2015
Сообщения
3 916
Благодарностей
3 852
Баллы
113
в мускуле есть свои локи
транзакции могут только хуже сделать в данном случае, т.к. залочив всю таблицу - где-то свалится исключение, хотя оно не желательно
 

doc

Client
Регистрация
30.03.2012
Сообщения
8 605
Благодарностей
4 595
Баллы
113
транзакции могут только хуже сделать в данном случае, т.к. залочив всю таблицу - где-то свалится исключение, хотя оно не желательно
я говорил о локах, а не о транзакциях
 

Lord_Alfred

Client
Регистрация
09.10.2015
Сообщения
3 916
Благодарностей
3 852
Баллы
113

doc

Client
Регистрация
30.03.2012
Сообщения
8 605
Благодарностей
4 595
Баллы
113

Lord_Alfred

Client
Регистрация
09.10.2015
Сообщения
3 916
Благодарностей
3 852
Баллы
113

doc

Client
Регистрация
30.03.2012
Сообщения
8 605
Благодарностей
4 595
Баллы
113

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 941
Благодарностей
4 331
Баллы
113

Lord_Alfred

Client
Регистрация
09.10.2015
Сообщения
3 916
Благодарностей
3 852
Баллы
113

doc

Client
Регистрация
30.03.2012
Сообщения
8 605
Благодарностей
4 595
Баллы
113
не слышал о них, можно подробнее, применимо к текущему вопросу?


как в итоге выглядит в зенке?
ну ты даёшь запрос гет лок с именем лока и вроде максимальным временем жизни. Дальше твои запросы. Дальше освобождение лока. Насколько я понимаю, любой другой гет_лок с именем этого же лока будет ожидать освобождения
 

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 941
Благодарностей
4 331
Баллы
113
  • Спасибо
Реакции: nicanil, proffman и one

Lord_Alfred

Client
Регистрация
09.10.2015
Сообщения
3 916
Благодарностей
3 852
Баллы
113
ну ты даёшь запрос гет лок с именем лока и вроде максимальным временем жизни. Дальше твои запросы. Дальше освобождение лока. Насколько я понимаю, любой другой гет_лок с именем этого же лока будет ожидать освобождения
Надо будет изучить этот вопрос, любопытно, спасибо)

@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 иметь какую-то свою логику
 

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 941
Благодарностей
4 331
Баллы
113

one

Client
Регистрация
22.09.2015
Сообщения
6 790
Благодарностей
1 264
Баллы
113
Код:
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 в переменной?
 

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 941
Благодарностей
4 331
Баллы
113

one

Client
Регистрация
22.09.2015
Сообщения
6 790
Благодарностей
1 264
Баллы
113
Я проверил у себя, нет, не подхватывает. Только если второй раз запустить экшен. Правда конструкция запросов немного другая.
 

Koqpe

Client
Регистрация
23.12.2014
Сообщения
1 100
Благодарностей
649
Баллы
113

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 941
Благодарностей
4 331
Баллы
113

one

Client
Регистрация
22.09.2015
Сообщения
6 790
Благодарностей
1 264
Баллы
113
Спасибо, попробую.
Странно, у меня все работает одним запросом.
Ну вот моя конструкция. 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-}';
 

one

Client
Регистрация
22.09.2015
Сообщения
6 790
Благодарностей
1 264
Баллы
113
Странно, у меня все работает одним запросом.
В твоем случае все работает видимо потому что в переменной уже есть данные. А у меня SELECT получает в переменную а UPDATE использует из переменной.
 

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 941
Благодарностей
4 331
Баллы
113
А вот ещё такая задачка
Нужно сделать SELECT keywords FROM links WHERE post = '0';
но при этом взять, скажем, только 100 первых рядов удовлетворяющих условию post = '0' и из этих 100 взять только 1 случайный ряд.
И всё это одним запросом.
 

Lord_Alfred

Client
Регистрация
09.10.2015
Сообщения
3 916
Благодарностей
3 852
Баллы
113
А вот ещё такая задачка
Нужно сделать 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

Astraport

Client
Регистрация
01.05.2015
Сообщения
4 941
Благодарностей
4 331
Баллы
113
Но нужно потестировать производительность, сталкивался что из-за RAND в запросе - очень сильно падала скорость выборки
Спасибо, проверю. Скорость особо не критична.
 

Rooter85

Client
Регистрация
04.07.2015
Сообщения
244
Благодарностей
63
Баллы
28
Подскажите как можно обновить несколько полей записи из файла.
Делаю так
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)
получается ошибка.
 

one

Client
Регистрация
22.09.2015
Сообщения
6 790
Благодарностей
1 264
Баллы
113
Попробовал выше метод лока в одном шаблоне. В принципе все ничего, одно но, потоки отваливаются не успев дождаться пока лок снимется. Конфиг MySQL надо править?
 

boorik2

Client
Регистрация
10.04.2017
Сообщения
202
Благодарностей
62
Баллы
28
  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;
    Локается вся таблица?
    или только строки, с которыми связан запрос?
 

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