Гость
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Работа с базой данных в несколько потоков / 25 сообщений из 37, страница 1 из 2
24.06.2021, 21:51
    #40079986
Timein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Добрый вечер!

У меня такой вопрос: у меня есть таблица table_state с тремя полями - id, date, state. Мне нужно в приложении в несколько потоков получать из таблицы данные. Каждый поток за один раз должен получать одну запись и эти записи не должны повторяться. Сейчас я делаю это через update поля state, то есть в рамках одной транзакции сначала
Код: plsql
1.
 select * from table_state where state = 'READY' and /*простое условие выборки одной записи*/

, а потом
Код: plsql
1.
 update table_state set state = 'UPDATE' where id = :id and  state = 'READY'


Использую для работы с базой Spring JdbcTemplate

1. Не будет ли у меня ситуаций, что я апдейчу уже обновленную строку? Использую Оракл, и насколько я знаю, у него по умолчанию Read committed.
2. Можно ли как-то более оптимально отбирать записи, чтобы не приходилось отбрасывать те, которые не удалось обновить?
...
Рейтинг: 0 / 0
24.06.2021, 22:21
    #40079990
SpringMan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Timein

1. Не будет ли у меня ситуаций, что я апдейчу уже обновленную строку? Использую Оракл, и насколько я знаю, у него по умолчанию Read committed.

Смотря в каком месте коммит, и как обрабатывается результат update-а
Timein

2. Можно ли как-то более оптимально отбирать записи, чтобы не приходилось отбрасывать те, которые не удалось обновить?

Вариантов много, надо подробнее знать, что происходит. Можно делить записи по номеру потока, можно селектить в один поток и потом раскидывать на разные, можно селектить в один поток и пихать в очередь, можно вынести логику на уровень базы, и можно еще много что. Какая конкретно логика у приложения?
...
Рейтинг: 0 / 0
25.06.2021, 00:22
    #40079993
Timein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
SpringMan,

Выглядит это приблизительно так:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
    @Transactional
    public String getStateMetaData() {
        StateMetaData stateMetaData = jdbcTemplate.queryForObject("select id, date, state from table_state where state = 'READY' and ...", new StateMapper());
        if (stateMetaData != null) {
            int updateRow = jdbcTemplate.update("update table_state set state = 'UPDATE' where id = ? and  state = 'READY'", new Object[]{stateMetaData.getId()}, int.class);
            if (updateRow > 0) {
                return stateMetaData;
            }
        }
        return null;
    }


Соответственно, если удалось получить данные, они отдаются дальше для обработки, если нет, то метод отдает null

Селектить в один поток не получится, так как приложение развернуто на нескольких подах
...
Рейтинг: 0 / 0
25.06.2021, 04:05
    #40080005
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Идея многопоточного обновления "чтобы было" - так себе идея.
В своём желании "ускориться" вы создаёте в базе совершенно ненужную конкуренцию за ресурсы.
...
Рейтинг: 0 / 0
25.06.2021, 04:47
    #40080007
Sergunka
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Basil A. Sidorov
Идея многопоточного обновления "чтобы было" - так себе идея.
В своём желании "ускориться" вы создаёте в базе совершенно ненужную конкуренцию за ресурсы.


Хотелось бы все таки понять, чего добивается автор таким дизайном. Там куда не копни везде засады. Если у него там таблица на миллионо записей вряд ли он сумеет миллион потоков обеспечить.
И вообще какое количество записей и какой SLA (service-level agreements).
...
Рейтинг: 0 / 0
25.06.2021, 07:00
    #40080010
Андрей Панфилов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Timein,

вам нужен for update skip locked
...
Рейтинг: 0 / 0
25.06.2021, 07:05
    #40080011
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Timein,

Не понял в чем вопрос.
В пределах потока события и код идут строго последовательно.
- взял
- подумал
- изменил
- положил.
- коммит
Даже если ты эти 4 действия делаешь один час, то они не параллельны.
Значит вопрос в другом - как не ошибиться чтобы 2 потока не взяли одну запись?
На этот вопрос ответ простой.
Распредели заранее записи. Без where.
Сделай коммит как можно быстрее
Сделай чтобы повтор обработки раз в день не ломал ИС
...
Рейтинг: 0 / 0
25.06.2021, 07:20
    #40080015
Sergunka
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
PetroNotC Sharp
Timein,

Не понял в чем вопрос.
В пределах потока события и код идут строго последовательно.
- взял
- подумал
- изменил
- положил.
- коммит
Даже если ты эти 4 действия делаешь один час, то они не параллельны.
Значит вопрос в другом - как не ошибиться чтобы 2 потока не взяли одну запись?
На этот вопрос ответ простой.
Распредели заранее записи. Без where.
Сделай коммит как можно быстрее
Сделай чтобы повтор обработки раз в день не ломал ИС


Вообще в первом приблежении тянет на классическую задачу прдьюсер - консьюмер. Выгружаешь таблицу в очередь и потом расхватываешь как горячие пирожки через консьюмеров.
...
Рейтинг: 0 / 0
25.06.2021, 07:27
    #40080016
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Sergunka,
Этот паттерн подходит, но он для message oriented middleware.
А у ТС пока этой парадигмой не пахнет.
Может он в нее стремится, но решает то на уровне бд.
...
Рейтинг: 0 / 0
25.06.2021, 09:07
    #40080021
Работа с базой данных в несколько потоков
Типичное решение, как уже говорил Андрей Панфилов , это использовать select for update skip locked:
Код: plsql
1.
select * from table_state where state = 'READY' and /*простое условие выборки одной записи*/ for update skip locked

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, ну и соответственно все наделанные изменения можно будет тоже откатить.
...
Рейтинг: 0 / 0
25.06.2021, 09:32
    #40080024
Работа с базой данных в несколько потоков
Но! Т.к. у тебя Oracle, то как обычно все сделано через одно место.. С одной стороны хочется вытащить только 1 запись, с другой стороны rownum не решает эту проблему, т.к. он будет считать как заблокированные, так и не заблокированные записи . Соответственно если просто сделать where rownum=1, то мы наткнемся на заблокированную запись и просто остановимся не вернув ничего. Если же делать where rownum <= N , то в большинстве случаев будут блокироваться больше одной записи. Но если все-таки уметь обрабатывать задачи не по одной, тогда все норм.
...
Рейтинг: 0 / 0
25.06.2021, 09:32
    #40080025
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Stanislav Bashkyrtsev,
Лочат записи когда непонятно кто берет их для обработки.
Если менеджер обработки одно лицо, то лочить самому себе странно.
...
Рейтинг: 0 / 0
25.06.2021, 09:33
    #40080026
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Stanislav Bashkyrtsev,
В оракле лочить просто плохой тон. Неблокировочник.
...
Рейтинг: 0 / 0
25.06.2021, 10:15
    #40080040
Timein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Sergunka
Basil A. Sidorov
Идея многопоточного обновления "чтобы было" - так себе идея.
В своём желании "ускориться" вы создаёте в базе совершенно ненужную конкуренцию за ресурсы.


Хотелось бы все таки понять, чего добивается автор таким дизайном. Там куда не копни везде засады. Если у него там таблица на миллионо записей вряд ли он сумеет миллион потоков обеспечить.
И вообще какое количество записей и какой SLA (service-level agreements).


PetroNotC Sharp
Stanislav Bashkyrtsev,
Лочат записи когда непонятно кто берет их для обработки.
Если менеджер обработки одно лицо, то лочить самому себе странно.


Записей не прям миллионы, но довольно большое количество.
Многопоточность будет в любом случае - у меня несколько подов, соответственно, несколько инстансов приложений

PetroNotC Sharp
Значит вопрос в другом - как не ошибиться чтобы 2 потока не взяли одну запись?
На этот вопрос ответ простой.
Распредели заранее записи. Без where.

Да, в целом именно в этом вопрос. И, собственное, хотелось бы понять, как заранее распределить записи. С учетом того, что у меня несколько инстансов приложений и они не знают ничего друг о друге
...
Рейтинг: 0 / 0
25.06.2021, 10:24
    #40080045
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Timein,
Разные инстансы приложений разве относится к многопоточости?
Опишите проблему или что не работает.
Ведь на sql.ru тоже пишут сообщения и ничего не знают друг от друга.
Неожиданно))))
...
Рейтинг: 0 / 0
25.06.2021, 11:14
    #40080063
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Если абстрагироваться от Oracle (заменить таблицу на очередь задач) - то сама задача
распределения тасок по джобам - решается в Java элементарно.

Так чего-же это мы так долго циклимся на способах блокирования datarows? Пускай 1 java-thread (singleton)
читает таблицу. Выдает задания. Проставляет статусы. И тогда целый технический пласт вопросов уходит.
...
Рейтинг: 0 / 0
25.06.2021, 11:16
    #40080068
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
mayton,
Я вот это его не понял
" у меня несколько подов, соответственно, несколько инстансов приложений")
...
Рейтинг: 0 / 0
25.06.2021, 11:37
    #40080078
Тролин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Timein
Добрый вечер!

У меня такой вопрос: у меня есть таблица table_state с тремя полями - id, date, state. Мне нужно в приложении в несколько потоков получать из таблицы данные. Каждый поток за один раз должен получать одну запись и эти записи не должны повторяться. Сейчас я делаю это через update поля state, то есть в рамках одной транзакции сначала
Код: plsql
1.
 select * from table_state where state = 'READY' and /*простое условие выборки одной записи*/

, а потом
Код: plsql
1.
 update table_state set state = 'UPDATE' where id = :id and  state = 'READY'


Использую для работы с базой Spring JdbcTemplate

1. Не будет ли у меня ситуаций, что я апдейчу уже обновленную строку? Использую Оракл, и насколько я знаю, у него по умолчанию Read committed.
2. Можно ли как-то более оптимально отбирать записи, чтобы не приходилось отбрасывать те, которые не удалось обновить?


Потом 100% будешь переписывать все под rabbit MQ или подобное.
...
Рейтинг: 0 / 0
25.06.2021, 11:58
    #40080084
Timein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
mayton
Если абстрагироваться от Oracle (заменить таблицу на очередь задач) - то сама задача
распределения тасок по джобам - решается в Java элементарно.

Так чего-же это мы так долго циклимся на способах блокирования datarows? Пускай 1 java-thread (singleton)
читает таблицу. Выдает задания. Проставляет статусы. И тогда целый технический пласт вопросов уходит.


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

Мы когда-то делали распределение задач по потокам на основе остатков от деления на количество потоков. Но тут есть засада, если количество потоков поменяется - как подхватить чужие брошенные задачи
...
Рейтинг: 0 / 0
25.06.2021, 12:04
    #40080090
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Timein,
Че за ерунда.
К базе ходят соединения из пула потоков. Обычно.
Если вы руками не делаете new thread
...
Рейтинг: 0 / 0
25.06.2021, 12:11
    #40080091
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Timein,
Для потоков и коннектов к бд придумали Пул.
Подумайте про эту мысль. Используете?
...
Рейтинг: 0 / 0
25.06.2021, 12:16
    #40080094
Timein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
PetroNotC Sharp, используем как пулы потоков, так и пулы коннектов, но пока не уловил вашу мысль, при чем тут это
...
Рейтинг: 0 / 0
25.06.2021, 12:23
    #40080098
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Timein
PetroNotC Sharp, используем как пулы потоков, так и пулы коннектов, но пока не уловил вашу мысль, при чем тут это

А как ваше знание соотносится с этим?
авторВ рамках одного приложения я могу сделать один поток.
Это надо расшифровать.
...
Рейтинг: 0 / 0
25.06.2021, 12:24
    #40080099
Работа с базой данных в несколько потоков
Timein , я не думаю что там есть глубокая мысль, просто Petro как обычно не понимает проблему. У тебя вполне типичная задача, специально для ее решения создан select for update skip locked . Это прям применение "по книге".
...
Рейтинг: 0 / 0
25.06.2021, 12:25
    #40080100
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с базой данных в несколько потоков
Timein,
Если страдает терминология, то попробуйте сделать Очень просто (без потоков) и потом сказать Проблему. Или ошибку.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Работа с базой данных в несколько потоков / 25 сообщений из 37, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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