Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Вопрос про блокировку строки / 8 сообщений из 8, страница 1 из 1
11.11.2017, 22:30
    #39551597
Lenics
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про блокировку строки
Добрый вечер. С блокировками, транзакциями и аналогичным, работать не приходилось. На днях искал решение задачи, но так и не добился положительных результатов или полного представления того, что мне всеж необходимо точно и как это найти.

Ситуация вот в чем. Имеется у меня дерево задач, у каждой ID автоинкримент. Имеется 5-ть обработчиков, которые выполняют работу с данным списком параллельно.

Принцип работы заключается в том, что каждый из них запрашивает строку, где статус выполнения = 0, и где демон_айди = 0, Limit 1.

После, присваивают по ID строки свой демон_айди и спокойно с ней работают. Видел некий набор типовых рекомендаций, для того, чтобы исключить выполнения работы с данной строкой несколькими демонами.
Самое интересно и простое в моем понимание было предложение использовать SELECT FOR UPDATE. Провел опыты, сделал запрос данного вида одним демоном, после не выполняя обновление каких-то данных данным демоном выполнил запрос вторым демоном. В итоге - он несмотря ни на какие FOR UPDATE спокойно взял данную строку и стал ее использовать.

Т.е. вариант, по каким-то причинам не проканал, либо я его не совсем верно понял.

В моем понимании, чтобы не было в случае каких-либо ошибок заблокированной пол таблицы, для меня, наверно, было бы оптимальнее всего просто при первом обращении к строке выполнять ее блокировку на некоторое время, к примеру, до 5-ть секунд, или до выполнения UPDATE ее, указывая явный ее ID. Чтобы, в это время, все остальные демоны просто проходили ее мимо.

Возможно, Вы предложите какие-то другие идеи по реализации, буду благодарен. Единственное, по возможности, предоставьте ответ чуть более развернутый, так как повторюсь - для меня такая задача совсем новая.


Таблица - InnoDB

Спасибо.
...
Рейтинг: 0 / 0
11.11.2017, 22:45
    #39551599
javajdbc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про блокировку строки
LenicsДобрый вечер. С блокировками, транзакциями и аналогичным, работать не приходилось. На днях искал решение задачи, но так и не добился положительных результатов или полного представления того, что мне всеж необходимо точно и как это найти.

Ситуация вот в чем. Имеется у меня дерево задач, у каждой ID автоинкримент. Имеется 5-ть обработчиков, которые выполняют работу с данным списком параллельно.

Принцип работы заключается в том, что каждый из них запрашивает строку, где статус выполнения = 0, и где демон_айди = 0, Limit 1.

После, присваивают по ID строки свой демон_айди и спокойно с ней работают. Видел некий набор типовых рекомендаций, для того, чтобы исключить выполнения работы с данной строкой несколькими демонами.
Самое интересно и простое в моем понимание было предложение использовать SELECT FOR UPDATE. Провел опыты, сделал запрос данного вида одним демоном, после не выполняя обновление каких-то данных данным демоном выполнил запрос вторым демоном. В итоге - он несмотря ни на какие FOR UPDATE спокойно взял данную строку и стал ее использовать.

Т.е. вариант, по каким-то причинам не проканал, либо я его не совсем верно понял.

В моем понимании, чтобы не было в случае каких-либо ошибок заблокированной пол таблицы, для меня, наверно, было бы оптимальнее всего просто при первом обращении к строке выполнять ее блокировку на некоторое время, к примеру, до 5-ть секунд, или до выполнения UPDATE ее, указывая явный ее ID. Чтобы, в это время, все остальные демоны просто проходили ее мимо.

Возможно, Вы предложите какие-то другие идеи по реализации, буду благодарен. Единственное, по возможности, предоставьте ответ чуть более развернутый, так как повторюсь - для меня такая задача совсем новая.


Таблица - InnoDB

Спасибо.


...вариантов несколько, напромер (на мой взгляд) самый простой:

1. выполнить апдейт

update table1
set daemon_id = <THIS_DAEMON_ID> -- ИД конкретного демона
,status = 'INPROGRESS'
where daemon_id in null -- незанятые задачи
and status = 'CREATED' -- надо продумать стейт-машину
order by insert_time --- взять первый по времени создания задачи
limit 1

далее:
проверить что UPDATE_COUNT равен 1, если нет -- повторить через 30 секунд --
например если свободных задач пока нет

затем

select *
from table 1
where
daemon_id = <THIS_DAEMON_ID> -- ИД конкретного демона
,status = 'INPROGRESS'

и спокойно работать над задачей....
...
Рейтинг: 0 / 0
11.11.2017, 22:51
    #39551601
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про блокировку строки
javajdbcдалее:
проверить что UPDATE_COUNT равен 1
Нафига? Надо сразу делать SELECT - и вот тут смотреть, сколько записей вернулось. Одна? работаем. Ноль? ждём (30 секунд более чем дофига, рандом от 0.1 до 1 сек. достаточно). Две и более? паникуем, ибо не бывает. А по какой причине ноль - нет задач, или задачу кто-то перехватил,- какая в общем разница?
...
Рейтинг: 0 / 0
11.11.2017, 23:04
    #39551605
Lenics
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про блокировку строки
Спасибо, тоже думал, первоначально сделать обновление 1-ной строки на нужную. Но, таких решения (практических), я не нашел. Иска не потому, что не знаю, как сделать, а потому, что не знаю, какие могут последствия и грабли. + от этой идеи отказался, когда все аналогичные запросы твердят про блокировки, к примеру. На сколько практично использовать данный подход? Почему аналогичные решения пытаются решить с помощью Блокировок\Транзакций?
...
Рейтинг: 0 / 0
11.11.2017, 23:06
    #39551606
Lenics
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про блокировку строки
Akina,

Спасибо за предложение, тут уже детали, как получить ключ. Меня больше сам подход интересует.
...
Рейтинг: 0 / 0
12.11.2017, 14:43
    #39551706
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про блокировку строки
Лучше и надёжнее сделать один диспечер, который соло, без блокировок и прочих толканий локтями выбирает записи и раскидывает их обработчикам. Они ему отчитываются о выполнении, после чего он им даёт новое задание. Синхронизировать работу через БД - тот ещё геморрой и решение всё равно обычно сводится к эксклюзивной блокировке целой таблицы.
...
Рейтинг: 0 / 0
12.11.2017, 16:54
    #39551732
Lenics
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про блокировку строки
Dimitry Sibiryakov,

Спасибо за совет. А можете чуть подробнее, возможно на каком-то примере показать данную реализацию или схематику процесса.

По хорошему, я понимаю, что вариантом может быть -- реббитмку, который может и информировать о статусе выполнения и забирать \ передавать воркерам необходимые данные. Но это отдельное решение, которые которое не всегда можно применять.

Как я понял, Ваш совет, отдельный обработчик при обращении к нему выдает задачу, после проверяет ее на выполнение. Если не отписался демон о ее выполнении, то данная задача назначается другому исполнителю.
...
Рейтинг: 0 / 0
16.11.2017, 07:44
    #39553988
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос про блокировку строки
Lenics,

потому что select ... for update надо делать в транзакции, а не просто так.


start transaction;

select ...
for update
from mytable
where ,...;

...

update mytable
set ...
where ...;

commit;
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Вопрос про блокировку строки / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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