Как отменить длительную операцию базы данных?

В настоящее время работает с Oracle, но также потребуется решение для MS SQL.

У меня есть графический интерфейс, который позволяет пользователям генерировать SQL, который будет выполнен в базе данных. Это может занять очень много времени, в зависимости от поиска, который они создают. Я хочу, чтобы GUI / App реагировал во время этого поиска, и я хочу, чтобы пользователь мог отменить поиск.

Я использую тему рабочего рабочего.

Моя проблема в том, что, когда пользователь отменяет поиск, я не могу прерывать вызов в базу данных. Он ждет, пока он не будет завершен, и затем он сможет опросить свойство «Отмена». Это не только ресурсы отходов в базе данных, но и создает проблемы для моего кода.

Если пользователь нажимает «Поиск» по очень длинному запросу, затем нажимает «Отмена», а затем снова «Поиск» – первый поиск по-прежнему прерывается в базе данных. Фоновый рабочий все еще занят, когда они снова находят поиск. Единственное решение, с которым я столкнулся, состоит в том, чтобы создать нового фонового работника.

Кажется, это действительно уродливый способ сделать что-то. База данных продолжает работать. Я создаю новые экземпляры фоновых работников …. когда я действительно хочу остановить вызов базы данных и повторно использовать одного и того же работника.

Как я могу это сделать?

Я не думаю, что это возможно. Вот ссылка на дискуссию на веб-сайте Oracle по этой теме: http://forums.oracle.com/forums/thread.jspa?threadID=400492&start=15&tstart=0

Если вы используете поставщик данных ADO.NET и SQL, посмотрите на метод SqlCommand.Cancel. Это делает то, что вы ищете. Тем не менее, он пытается отменить, и отмена может занять некоторое время. В основном, SQL Server должен решить, когда следует предоставить запрос на отмену. Когда запрос отменяется, вы должны получить исключение SqlException, которое указывает, что операция была отменена пользователем. По-видимому, вы не хотите рассматривать это исключение как исключение и обрабатывать его специально, например, если SqlException вызван тем, что пользователь отменил операцию, просто проглотите ее.

Я также заметил, что command.Cancel () не отменяет команду. То, что сработало для меня, – это закрытие соединения (транзакция возврата, если вы используете ее), когда пользователь прерывается. Это приведет к возникновению исключения в фоновом streamе во время выполнения команды, поэтому вам придется поймать его и проверить свойство CancellationPending, а не отменять исключение в этом случае …

// When aborting worker.CancelAsync(); command.Connection.Close(); // In your DoWork event handler ... catch (Exception) { if (worker.CancellationPending) { e.Cancel = true; return; } else { throw; } } // And in your RunWorkerCompleted event handler if (e.Error == null && !e.Cancelled) { ... } 

Я уверен, что это возможно – мы используем TOAD для Oracle, и он позволяет отменить длительные запросы, как описано здесь . Я не уверен, как они это делают.

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

Я думаю, что лучшее решение, похоже, убивает сеансы через таблицу мониторинга.

С Oracle вы можете сделать это, как говорит Burnsys

В Firebird 2.5 он будет выглядеть одинаково

Я надеюсь, что что-то подобное существует в Ms SQL

Если вы используете SQLCommand, вы можете попробовать вызвать метод « Отмена» .

Как насчет открытия нового подключения к базе данных, войдите в систему как sysdba и отправьте команду «ALTER SYSTEM KILL SESSION» sid, серийный номер «IMMEDIATE», указав SID процесса, который вы хотите завершить.

Чтобы получить sessionID: выберите sid из v $ mystat, где rownum = 1

Чтобы получить Serial #: выберите sid, serial # из v $ session, где sid =: SID

http://www.oracle-base.com/articles/misc/KillingOracleSessions.php

EDIT: идея WWW не для входа в систему как sysdba здесь: http://forums.oracle.com/forums/thread.jspa?threadID=620578

Я пробовал как Отменить, так и закрыть с ADO 2.8 и SQLOLEDB или SQL Server родным клиентом. С помощью Отмена набор записей перестает извлекать данные, но на заднем плане чтение с сервера продолжается и потребляет память из приложения. В 32-битном приложении может случиться, что через несколько минут вы получите сообщение «из памяти». Когда я закрываю набор записей (или соединение, с или без отмены до), ADO 2.8 ждет, пока все записи не будут извлечены.

Я не знаю, улучшает ли ADO.NET, но я думаю, что неплохо следить за памятью и доступом к сети после Cancel / Close, чтобы быть уверенным, что ADO действительно перестает читать данные.

  • Получить идентификатор последней вставленной записи в oracle db
  • Связывание параметров OracleCommand SQL
  • Perl DBD :: Установка модуля Oracle
  • как петля принимает ввод пользователя с помощью pl / sql?
  • ORA-30926: невозможно получить стабильный набор строк в исходных таблицах
  • OracleDataSource против Oracle UCP PoolDataSource
  • ORA-01461: может связывать значение LONG только для вставки в столбцы LONG. Происходит при запросе
  • Можно ли создавать модели django из базы данных?
  • Различные CURRENT_TIMESTAMP и SYSDATE в oracleе
  • PLSQL JDBC: как получить идентификатор последней строки?
  • Проблема HIbernate с Oracle Trigger для генерации идентификатора из последовательности
  • Давайте будем гением компьютера.