Принудительное закрытие оракула в C # - PullRequest
8 голосов
/ 08 февраля 2011

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

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

Я пытался вызвать Close для соединения из другого потока, но это, кажется, постоянно блокируется.Я также попытался откатить транзакцию, но в ней возникает та же проблема.

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

Вполне вероятно, что я упускаю что-то очевидное, любая помощь будет принята с благодарностью.

ПОЖАЛУЙСТА, ПРОЧИТАЙТЕ

Этот вопрос не касается оборачивания моего соединения вusing заявление.Речь идет о том, как принудительно закрыть соединение оракула, выполняющего запрос, .

Пример:

  • Запустить поток, выполняющий запрос
  • Где-то спрятать объект соединения
  • Вызов закрыть объект соединения

    public void Go()
    {
        OracleConnection connection;
        var queryThread = new Thread(
            () =>
                {
                    using (connection = OpenOracleConnection())
                    {
                        // execute stored proc that takes 45 mins
                        // raise an event with the data set we load
                    }
                });
    
        Thread.Sleep(3000); // give it time to be useless
    
        var closeThread = new Thread(
            () =>
                {
                    connection.Close();
                });
        closeThread.Start();
    }
    

Проблема в том, что вместо этого соединение не закрываетсявызов connection.Close () блокирует ожидание выполнения процедуры.

Ответы [ 3 ]

3 голосов
/ 08 февраля 2011

Хм, я не вижу ничего в API, чтобы прервать / отменить текущий запрос. Технически должно быть возможно, во втором сеансе с полными привилегиями, идентифицировать сеанс, который вы хотите прервать, и выполнить команду kill session в этом сеансе. Я бы ожидал, что ваша исходная сессия выручит за какое-то исключение, но я никогда не пробовал.

Здесь объясняется, как завершить сеанс.

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

Дайте нам знать, если это работает;)

1 голос
/ 08 февраля 2011

Чтобы увидеть, что / кто блокирует, кто:

select s1.username || '@' || s1.machine
   || ' ( SID=' || s1.sid || ' )  is blocking '
   || s2.username || '@' || s2.machine || ' ( SID=' || s2.sid || ' ) ' AS status
   from v$lock l1, v$session s1, v$lock l2, v$session s2
   where s1.sid=l1.sid and s2.sid=l2.sid
   and l1.BLOCK=1 and l2.request > 0
   and l1.id1 = l2.id1
   and l2.id2 = l2.id2;
0 голосов
/ 08 февраля 2011

Как и с любым провайдером в .NET, вы можете позвонить Dispose

using(var conn = /* your connection */) {
    // do your stuff

    conn.Close();
} // this will automatically call .Dispose()

Так что это все, что вам нужно сделать.

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