|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Добрый вечер! У меня такой вопрос: у меня есть таблица table_state с тремя полями - id, date, state. Мне нужно в приложении в несколько потоков получать из таблицы данные. Каждый поток за один раз должен получать одну запись и эти записи не должны повторяться. Сейчас я делаю это через update поля state, то есть в рамках одной транзакции сначала Код: plsql 1.
, а потом Код: plsql 1.
Использую для работы с базой Spring JdbcTemplate 1. Не будет ли у меня ситуаций, что я апдейчу уже обновленную строку? Использую Оракл, и насколько я знаю, у него по умолчанию Read committed. 2. Можно ли как-то более оптимально отбирать записи, чтобы не приходилось отбрасывать те, которые не удалось обновить? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.06.2021, 21:51 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Timein 1. Не будет ли у меня ситуаций, что я апдейчу уже обновленную строку? Использую Оракл, и насколько я знаю, у него по умолчанию Read committed. Смотря в каком месте коммит, и как обрабатывается результат update-а Timein 2. Можно ли как-то более оптимально отбирать записи, чтобы не приходилось отбрасывать те, которые не удалось обновить? Вариантов много, надо подробнее знать, что происходит. Можно делить записи по номеру потока, можно селектить в один поток и потом раскидывать на разные, можно селектить в один поток и пихать в очередь, можно вынести логику на уровень базы, и можно еще много что. Какая конкретно логика у приложения? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.06.2021, 22:21 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
SpringMan, Выглядит это приблизительно так: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Соответственно, если удалось получить данные, они отдаются дальше для обработки, если нет, то метод отдает null Селектить в один поток не получится, так как приложение развернуто на нескольких подах ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 00:22 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Идея многопоточного обновления "чтобы было" - так себе идея. В своём желании "ускориться" вы создаёте в базе совершенно ненужную конкуренцию за ресурсы. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 04:05 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Basil A. Sidorov Идея многопоточного обновления "чтобы было" - так себе идея. В своём желании "ускориться" вы создаёте в базе совершенно ненужную конкуренцию за ресурсы. Хотелось бы все таки понять, чего добивается автор таким дизайном. Там куда не копни везде засады. Если у него там таблица на миллионо записей вряд ли он сумеет миллион потоков обеспечить. И вообще какое количество записей и какой SLA (service-level agreements). ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 04:47 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Timein, вам нужен for update skip locked ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 07:00 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Timein, Не понял в чем вопрос. В пределах потока события и код идут строго последовательно. - взял - подумал - изменил - положил. - коммит Даже если ты эти 4 действия делаешь один час, то они не параллельны. Значит вопрос в другом - как не ошибиться чтобы 2 потока не взяли одну запись? На этот вопрос ответ простой. Распредели заранее записи. Без where. Сделай коммит как можно быстрее Сделай чтобы повтор обработки раз в день не ломал ИС ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 07:05 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
PetroNotC Sharp Timein, Не понял в чем вопрос. В пределах потока события и код идут строго последовательно. - взял - подумал - изменил - положил. - коммит Даже если ты эти 4 действия делаешь один час, то они не параллельны. Значит вопрос в другом - как не ошибиться чтобы 2 потока не взяли одну запись? На этот вопрос ответ простой. Распредели заранее записи. Без where. Сделай коммит как можно быстрее Сделай чтобы повтор обработки раз в день не ломал ИС Вообще в первом приблежении тянет на классическую задачу прдьюсер - консьюмер. Выгружаешь таблицу в очередь и потом расхватываешь как горячие пирожки через консьюмеров. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 07:20 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Sergunka, Этот паттерн подходит, но он для message oriented middleware. А у ТС пока этой парадигмой не пахнет. Может он в нее стремится, но решает то на уровне бд. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 07:27 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Типичное решение, как уже говорил Андрей Панфилов , это использовать select for update skip locked: Код: plsql 1.
1. tx1 залочила запись 2. tx2 в нее упирается, видит что та залочена и просто идет к следующей записи Мы наверно хотим чтоб каждый поток работал только над одной задачей, поэтому еще про limit/rownum не забываем. Timein1. Не будет ли у меня ситуаций, что я апдейчу уже обновленную строку? Использую Оракл, и насколько я знаю, у него по умолчанию Read committed.Проблема в том что ты сможешь сделать одновременный select. И два потока будут работать над одной задачей. Обновления сами по себе конфликтовать не будут, кто первый - того и тапки: 1. tx1 обновит запись, меняет state на 'UPDATE' 2. tx2 заблокируется на этой записи пока tx1 не закончится 3. tx2 наконец-таки разблокируется, однако у записи уже state поменялся, поэтому условие and state = 'READY' пропустит эту запись и ничего не обновит. Т.е. and STATE='READY' в данном случае сработает в качестве оптимистической блокировки. Обратно в Java прийдет что кол-во обновленных строк=0, ну и соответственно все наделанные изменения можно будет тоже откатить. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 09:07 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Но! Т.к. у тебя Oracle, то как обычно все сделано через одно место.. С одной стороны хочется вытащить только 1 запись, с другой стороны rownum не решает эту проблему, т.к. он будет считать как заблокированные, так и не заблокированные записи . Соответственно если просто сделать where rownum=1, то мы наткнемся на заблокированную запись и просто остановимся не вернув ничего. Если же делать where rownum <= N , то в большинстве случаев будут блокироваться больше одной записи. Но если все-таки уметь обрабатывать задачи не по одной, тогда все норм. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 09:32 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Stanislav Bashkyrtsev, Лочат записи когда непонятно кто берет их для обработки. Если менеджер обработки одно лицо, то лочить самому себе странно. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 09:32 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Stanislav Bashkyrtsev, В оракле лочить просто плохой тон. Неблокировочник. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 09:33 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Sergunka Basil A. Sidorov Идея многопоточного обновления "чтобы было" - так себе идея. В своём желании "ускориться" вы создаёте в базе совершенно ненужную конкуренцию за ресурсы. Хотелось бы все таки понять, чего добивается автор таким дизайном. Там куда не копни везде засады. Если у него там таблица на миллионо записей вряд ли он сумеет миллион потоков обеспечить. И вообще какое количество записей и какой SLA (service-level agreements). PetroNotC Sharp Stanislav Bashkyrtsev, Лочат записи когда непонятно кто берет их для обработки. Если менеджер обработки одно лицо, то лочить самому себе странно. Записей не прям миллионы, но довольно большое количество. Многопоточность будет в любом случае - у меня несколько подов, соответственно, несколько инстансов приложений PetroNotC Sharp Значит вопрос в другом - как не ошибиться чтобы 2 потока не взяли одну запись? На этот вопрос ответ простой. Распредели заранее записи. Без where. Да, в целом именно в этом вопрос. И, собственное, хотелось бы понять, как заранее распределить записи. С учетом того, что у меня несколько инстансов приложений и они не знают ничего друг о друге ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 10:15 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Timein, Разные инстансы приложений разве относится к многопоточости? Опишите проблему или что не работает. Ведь на sql.ru тоже пишут сообщения и ничего не знают друг от друга. Неожиданно)))) ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 10:24 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Если абстрагироваться от Oracle (заменить таблицу на очередь задач) - то сама задача распределения тасок по джобам - решается в Java элементарно. Так чего-же это мы так долго циклимся на способах блокирования datarows? Пускай 1 java-thread (singleton) читает таблицу. Выдает задания. Проставляет статусы. И тогда целый технический пласт вопросов уходит. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 11:14 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
mayton, Я вот это его не понял " у меня несколько подов, соответственно, несколько инстансов приложений") ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 11:16 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Timein Добрый вечер! У меня такой вопрос: у меня есть таблица table_state с тремя полями - id, date, state. Мне нужно в приложении в несколько потоков получать из таблицы данные. Каждый поток за один раз должен получать одну запись и эти записи не должны повторяться. Сейчас я делаю это через update поля state, то есть в рамках одной транзакции сначала Код: plsql 1.
, а потом Код: plsql 1.
Использую для работы с базой Spring JdbcTemplate 1. Не будет ли у меня ситуаций, что я апдейчу уже обновленную строку? Использую Оракл, и насколько я знаю, у него по умолчанию Read committed. 2. Можно ли как-то более оптимально отбирать записи, чтобы не приходилось отбрасывать те, которые не удалось обновить? Потом 100% будешь переписывать все под rabbit MQ или подобное. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 11:37 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
mayton Если абстрагироваться от Oracle (заменить таблицу на очередь задач) - то сама задача распределения тасок по джобам - решается в Java элементарно. Так чего-же это мы так долго циклимся на способах блокирования datarows? Пускай 1 java-thread (singleton) читает таблицу. Выдает задания. Проставляет статусы. И тогда целый технический пласт вопросов уходит. В рамках одного приложения я могу сделать один поток. Но у меня несколько приложений (пусть будет три), то есть мы получаем уже три потока, ходящих к базе данных. И тогда возвращаемся к вопросу, как сделать так, чтобы потоки не ухватили одновременно одну и ту же запись. Поправьте меня, пожалуйста, если это не совпадает с задачей - несколько потоков в одном приложении (хотя в одном приложении мне кажется все проще решить) Мы когда-то делали распределение задач по потокам на основе остатков от деления на количество потоков. Но тут есть засада, если количество потоков поменяется - как подхватить чужие брошенные задачи ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 11:58 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Timein, Че за ерунда. К базе ходят соединения из пула потоков. Обычно. Если вы руками не делаете new thread ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 12:04 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Timein, Для потоков и коннектов к бд придумали Пул. Подумайте про эту мысль. Используете? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 12:11 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
PetroNotC Sharp, используем как пулы потоков, так и пулы коннектов, но пока не уловил вашу мысль, при чем тут это ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 12:16 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Timein PetroNotC Sharp, используем как пулы потоков, так и пулы коннектов, но пока не уловил вашу мысль, при чем тут это А как ваше знание соотносится с этим? авторВ рамках одного приложения я могу сделать один поток. Это надо расшифровать. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 12:23 |
|
Работа с базой данных в несколько потоков
|
|||
---|---|---|---|
#18+
Timein , я не думаю что там есть глубокая мысль, просто Petro как обычно не понимает проблему. У тебя вполне типичная задача, специально для ее решения создан select for update skip locked . Это прям применение "по книге". ... |
|||
:
Нравится:
Не нравится:
|
|||
25.06.2021, 12:24 |
|
|
start [/forum/topic.php?fid=59&msg=40080007&tid=2120412]: |
0ms |
get settings: |
18ms |
get forum list: |
5ms |
check forum access: |
1ms |
check topic access: |
1ms |
track hit: |
35ms |
get topic data: |
2ms |
get forum data: |
1ms |
get page messages: |
466ms |
get tp. blocked users: |
0ms |
others: | 366ms |
total: | 895ms |
0 / 0 |