Остановить поток Java, который вызывает процедуру Oracle - PullRequest
2 голосов
/ 04 августа 2010

В веб-приложении Spring / Hibernate я использую рабочую очередь, созданную с помощью потоков Java. Метод run() в Threads вызывает процедуру Oracle, которая может длиться несколько минут / часов. Все потоки рабочей очереди хранятся в списке.

Я хотел бы создать интерфейс (JSP), в котором я мог бы отобразить список запущенных заданий и позволить пользователям «убивать» задание.

Я не могу использовать метод Thread.stop(), который устарел. Я также уже пробовал различные методы с interrupt(), но мне не удалось остановить поток во время вызова Oracle.

  • Как вы думаете, возможно ли остановить поток во время вызова Oracle?
  • В противном случае, я должен искать другой способ сделать эту рабочую очередь (без потоков)?

Большое спасибо!

Ответы [ 4 ]

2 голосов
/ 04 августа 2010

"Должен ли я искать другой способ сделать эта рабочая очередь (без потоков) "

Мне кажется, что вы заново изобретаете функциональность работы с базой данных, которую уже предоставляет Oracle.

Существует DBMS_SCHEDULER , который был представлен в Oracle 10g, который довольно сложен. В более ранних версиях есть только DBMS_JOB , что все еще довольно хорошо: он лучше справится с работой хранимых процедур в фоновом режиме, чем ваша текущая реализация.

1 голос
/ 04 августа 2010

Вам необходимо вызвать Statement.cancel () из веб-приложения, как указано в этом ответе для SO .Это может не привести к хорошей реализации, так как доступ к объекту Statement должен быть доступен через два потока как минимум, и это не обязательно хорошая практика программирования.

РЕДАКТИРОВАТЬ: В случае, если я не был достаточно ясен, вам нужно сохранить ссылки на объекты Statement, которые выполняют запросы, и сделать их доступными для операций отмены (которые будут выполняться в разных потоках), если пользователи решат отменить выполнениеработы.Если этот подход не удался (обычно из-за неверного предположения о безопасности потока объекта Statement), вы можете прервать выполнение потока оператором и отменить выполнение оператора из исходного потока.

0 голосов
/ 04 августа 2010

Это скорее резервная копия других ответов.

Большая проблема, с которой вы столкнетесь, заключается в том, что, хотя можно убить поток Java, блок pl / sql может продолжить выполняться на сервере некоторое время спустя.

У меня былоэта проблема с кодом C в прошлом, и вы можете либо попытаться отправить «отмена» на сервер и подождать, пока оно не будет подтверждено (что может быть никогда), либо «сделать все возможное», в любом случае прервать работающий поток,Позвольте очистить Oracle позже, когда он обнаружит, что клиентский процесс завершился.

Ответ APC хорош - это звучит как идеальный случай для фонового планировщика заданий Oracle, который предлагает хороший обзор выполнения задач иAPI для запуска / остановки / и т. Д.

Небольшое преимущество заключается в том, что вы не связываете соединения из своего пула соединений JDBC с длительными транзакциями.

Где, я думаю, у вас все еще может бытьпроблема остановки выполняющейся задачи в середине.Документация Oracle для DBMS_JOB гласит, что нет способа остановить задание после его запуска.

Одно из решений, которое я сделал, - периодически проверять фоновое задание на состояние выхода (т. Е. Существует ли строка втаблица) - но это работает, только если у вас есть цикл.

0 голосов
/ 04 августа 2010

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

Мой совет - либо позволить ему работать, но пометив потоку, что он должен выполнить ROLLBACK, когда это будет сделано в конце концов.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...