[MySQL] Работа с базой данных: Как работать в многопоточном режиме с разных устройств?

Livesferma

Client
Регистрация
22.10.2020
Сообщения
35
Благодарностей
5
Баллы
8
Доброго времени суток!

Столкнулся с проблемой, связанной с обработкой данных в базе. Мой шаблон берет первую строку из базы данных и удаляет её. Затем другой блок возвращает строку в конец базы. В результате этого возникают тысячи дубликатов строк.

Подскажите, пожалуйста, как создать адекватную очередь для обработки данных?

Я пробовал следующий код:

SQL:
LOCK TABLES proxy_by WRITE;

START TRANSACTION;

CREATE TEMPORARY TABLE temp_proxy AS
SELECT id, proxy FROM proxy_by LIMIT 1;

DELETE FROM proxy_by
WHERE id = (SELECT id FROM temp_proxy LIMIT 1);

COMMIT;

SELECT proxy FROM temp_proxy;

DROP TEMPORARY TABLE temp_proxy;

UNLOCK TABLES;
Однако некоторые устройства остаются в очереди навсегда.
 

Alex91

Активный пользователь
Регистрация
15.08.2024
Сообщения
656
Благодарностей
183
Баллы
43
База это не список... Нет более варварского способа , чем получать строку с удалением и заново добавлять ее в базу...

У строки в базе есть id и поля. Вот и надо оперировать данными из этих полей. Поставил таймштамп, что взял строку в работу, поставил таймштамп, что закончил работу со стройкой. Дополнительную логику можно реализовать , по проверке таймштампов взятых в работу, но превышившие лимиты обработки.
 

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 785
Благодарностей
1 397
Баллы
113
В БД нет тако же понятия первый-последний как вы привыкли в файлах/списках ... в результате одного запроса строка будет перовой, а в результате другого десятой, двадцать пятой или последней т.ч все эти понятия существуют лишь в рамках конкретного запроса.
Поэтому делать то что вы хотите лучше другим способом, а именно добавлением столбца с временем последнего использования прокси ... а брать прокси из таблицы соответственно запросом с сортировкой по этому столбцу (посл. время использования) в обратном порядке (то есть ту что не использовалась дольше всего)
 
  • Спасибо
Реакции: Livesferma

zarufakis

Client
Регистрация
22.03.2019
Сообщения
1 771
Благодарностей
1 160
Баллы
113
как создать адекватную очередь для обработки данных?
Добавь поле updated_at тип таймстамп и берите всегда самое старое.
Сделай в одной транзакции два запроса:
- берем самую старую запись, устанавливаем ему текущую дату, получаем ее айди
- по айди загружаем саму строку.

Чатгпт в помощь как это реализовать в твоем случае.
 
  • Спасибо
Реакции: kagorec и Livesferma

Livesferma

Client
Регистрация
22.10.2020
Сообщения
35
Благодарностей
5
Баллы
8
База это не список... Нет более варварского способа , чем получать строку с удалением и заново добавлять ее в базу...

У строки в базе есть id и поля. Вот и надо оперировать данными из этих полей. Поставил таймштамп, что взял строку в работу, поставил таймштамп, что закончил работу со стройкой. Дополнительную логику можно реализовать , по проверке таймштампов взятых в работу, но превышившие лимиты обработки.
Окей, а лочить таблицу все равно нужно? Чтобы другие потоки одновременно не обратились к одному timestamp?
 

backoff

Client
Регистрация
20.04.2015
Сообщения
6 162
Благодарностей
6 522
Баллы
113
Не надо удалять
бери строку по ID - это лучший способ, нагрузки нет, хоть в триллион потоков, после взятия строки делай UPDATE ее, добавляя статус, например "work" и все
 
  • Спасибо
Реакции: Livesferma

Alex91

Активный пользователь
Регистрация
15.08.2024
Сообщения
656
Благодарностей
183
Баллы
43
  • Спасибо
Реакции: Livesferma

Livesferma

Client
Регистрация
22.10.2020
Сообщения
35
Благодарностей
5
Баллы
8
Всем спасибо, работает. Выкладываю как сделал запрос, может кому пригодиться.

SQL:
START TRANSACTION;

-- Обновление временной метки и получение значения proxy
UPDATE proxy_by
SET updated_at = CURRENT_TIMESTAMP
WHERE id = (
    SELECT id FROM (
        SELECT id FROM proxy_by ORDER BY updated_at ASC LIMIT 1
    ) AS temp
);

-- Получение значения proxy после обновления временной метки
SELECT proxy FROM proxy_by
WHERE id = (
    SELECT id FROM (
        SELECT id FROM proxy_by ORDER BY updated_at ASC LIMIT 1
    ) AS temp
);

COMMIT;
 
  • Спасибо
Реакции: zarufakis и uf0log

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