Когда я вызываю PreparedStatement.cancel () в приложении JDBC, действительно ли оно уничтожает его в базе данных Oracle? - PullRequest
7 голосов
/ 18 марта 2009

У меня есть приложение Java JDBC, работающее с базой данных Oracle 10g. Я настроил PreparedStatement для выполнения запроса, а затем вызвал ps.executeQuery () для его выполнения. Иногда запрос занимает много времени, и мне нужно его убить. У меня есть другой поток доступа к этому объекту PreparedStatement и вызову cancel () для него.

У меня вопрос, это на самом деле убивает запрос в базе данных? Или это просто отрывает его от клиента, а запрос все еще выполняется где-то в недрах Oracle?

Спасибо!

Ответы [ 3 ]

10 голосов
/ 18 марта 2009

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

То, что ninesided сказал в первом абзаце, верно. Однако остерегайтесь предложенного теста. Не все длительные запросы оракула одинаковы. Похоже, что запросы оцениваются в два этапа: первый этап, который объединяет достаточное количество данных, чтобы знать, как вернуть строки в правильном порядке, и второй этап, который возвращает строки, заполняющие пробелы, которые он не вычислял в первая фаза. На разделение работы между двумя фазами также влияют настройки оптимизатора на основе затрат. например Первые строки против всех строк.

Теперь, если запрос находится на фазе 1, запрос на отмену в лучшем случае представляется в очередь для применения в конце фазы 1, что означает, что запрос продолжает работать.

На этапе 2 строки возвращаются в виде групп, и после каждой группы команда отмены может вступать в силу, поэтому, если драйвер поддерживает эту команду, запрос отмены приведет к уничтожению запроса.

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

8 голосов
/ 19 марта 2009

Ответ в том, что это проблема качества реализации. Если вы посмотрите на javadoc для Statement.cancel (), он говорит, что это произойдет, «если СУБД и драйвер поддерживают прерывание оператора SQL».

По моему опыту работы с различными версиями драйверов JDBC Oracle, Statement.cancel (), кажется, делает то, что вам нужно. Похоже, что запрос отменяется сразу после отмены.

1 голос
/ 18 марта 2009

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

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

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