powered by simpleCommunicator - 2.0.41     © 2025 Programmizd 02
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Имитация потоков, распределение задач
4 сообщений из 4, страница 1 из 1
Имитация потоков, распределение задач
    #39783326
Zhenek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день..
Есть необходимость делать много долгих запросов, поэтому написал цикл длинной в 60 сек,

выглядит примерно так:

Код: php
1.
2.
3.
4.
for($i=0;$i<60;$i++){

sleep(1);
}



Который раз в секунду делает запрос к БД и пытается получить задание

Код: sql
1.
SELECT * FROM tasks WHERE status='wait' LIMIT 1


Как только получает, сразу же делает update
Код: sql
1.
UPDATE tasks SET status='inwork' WHERE id='{id}'


и после выполнения завершает цикл. (выполнение от 50 до 300 сек)

Стоит 10 крон задач вызовом php -f, которые каждую минуту запускает 10 копий этого скрипта с указанием параметра, какой № этого потока.

Так вот, получается ожидая задачу крутит 10 таких циклов, и между SELECT и UPDATE два разных потока умудряются схватить 1 и ту-же задачу.

Пока решил это так: задача сразу назначается конкретному потоку (сначала свободным, потом менее занятым), но не во всех задачах это можно реализовать.

Как можно решить это на уровне SQL ? InnoDB
Читал про блокировки, но везде пишут, что в нагруженных проектах блокировки зло, надо без них... У меня не нагруженный проект совсем, по меркам тех же ОД,ВК и т.д. как решается это там?
...
Рейтинг: 0 / 0
Имитация потоков, распределение задач
    #39783341
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Имитация потоков, распределение задач
    #39783728
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторКак можно решить это на уровне SQL ? InnoDB
как вариант
в записи есть поле, которое инкриментится при каждом изменении, например, revision
тогда раз в секунду запрос к БД
Код: plsql
1.
SELECT id, revision FROM tasks WHERE status='wait' LIMIT 1


если что-то есть - попытка захватить запись
Код: plsql
1.
UPDATE tasks SET status='inwork', revision=revision+1 WHERE id='{id}' AND revision={revision}


где {revision} - значение полученное из селекта на пред шаге
если кол-во измененных записей = 1 - запись ваша, если нет, повторяем с начала


авторт.д. как решается это там?
есть вариант использовать очереди сообщений
...
Рейтинг: 0 / 0
Имитация потоков, распределение задач
    #39783911
Zhenek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторкак вариант
в записи есть поле, которое инкриментится при каждом изменении, например, revision
тогда раз в секунду запрос к БД
где {revision} - значение полученное из селекта на пред шаге
если кол-во измененных записей = 1 - запись ваша, если нет, повторяем с начала



Интересно... в принципе я могу просто дописать where status='wait'
т.к. если другой поток ее уже схватил, то кто-то из них все равно первым внесет изменения, не может быть 2 update одновременно..

автор https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html
С этим пока тоже разбираюсь.. Но почему-то мускуль ругается на LOCK или FOR UPDATE/SHARE
Думаю после праздников создать тестовую базу и там баловаться..

авторесть вариант использовать очереди сообщений
С этим тоже обязательно ознакомлюсь.

Всем большое спасибо, есть куда двигаться дальше)
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Имитация потоков, распределение задач
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]