Использование того же потока для других операций с базой данных после завершения обработки

#java #multithreading #hibernate #oracle11g #batch-processing

#java #многопоточность #спящий режим #oracle11g #пакетная обработка

Вопрос:

Я пишу приложение hibernate, которое включает пакетную обработку сохраненных записей.

Предположим, что в таблице базы данных хранится 30000 записей, и я использую 30 потоков. Каждый поток обрабатывает 1000 записей параллельно, т.Е. Пакет за пакетом. Thread1 обрабатывает от 1 до 1000 Thread2: от 1001 до 2001 и т.д. Здесь процесс означает, что я выполняю операцию выбора для всех из них в пакетном режиме. Я обрабатываю эти записи, чтобы отправить их в веб-службу путем их синтаксического анализа.

Сценарий заключается в том, что в таблице базы данных есть столбец с именем status, где, если запись принята веб-сервисом, тогда столбец status записи выполняется как 1, иначе 0.

Теперь проблема возникает здесь, когда Thread1 завершает обработку записей с идентификаторами от 1 до 1000, а поток 2 все еще обрабатывает от 1001 до 2001. Предположим, что записи с идентификаторами от 5 до 30 и от 40 до 50 имеют статус 0, т.Е. Не доставлены веб-сервису. Теперь мой сценарий требует, чтобы поток, который завершил обработку, т.Е. Thread1, начал обрабатывать записи с идентификаторами от 5 до 30 и от 40 до 50 и попытался повторно доставить сообщение в записи веб-сервису.

Я использую ExecutorService для кодирования то же самое, как достичь вышеуказанного.

Комментарии:

1. действительно ли select настолько тяжелый, что вам нужно использовать 30 потоков и для выбора? Как насчет использования 1 селектора потоков и 30 рабочих потоков?

2. Сколько ядер у вас есть в вашем распоряжении? Если это меньше 30, вы не получаете никакого распараллеливания из-за избытка, просто переключение контекста и перебор. Для меня это звучит как слишком сложный дизайн.

3. Нет, я уже думал об этом, обработка 30000 записей или даже больше, кто знает, одним потоком не рекомендуется, так как для обработки требуется много времени, и я забыл упомянуть в сообщении, что пакетная обработка записей и доставка в веб-сервис должны выполняться в течение ограниченного периода времени 15минут . На моей машине 8 ядер

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

5. Синтаксический анализ происходит в памяти, но проанализированное сообщение отправляется в webservice, и в зависимости от его статуса я присваиваю записи статус 1 или 0. Надеюсь, этого достаточно

Ответ №1:

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

Затем в вашем Thread коде каждый поток получает 1000 лучших (используя этот метод) записей из очереди и выполняет их обработку. Вот важная часть: записи, отклоненные веб-службой, помещаются обратно в очередь — поэтому, когда доступен другой поток исполнителя, он выберет недоставленные.

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