2011-02-08 24 views
5

長期間実行される可能性のあるOr​​acleストアド・プロシージャから返された結果を示すレポート・ウィンドウがあります。私の問題は、ユーザーがオラクルへの接続が開いたままで、潜在的に長時間実行されているレポートが取り消されないというウィンドウを閉じるときです。C#で強制的にOracle接続を閉じる

オープン接続を閉じる唯一の方法は、DBAが手動で強制終了するか、ユーザーがアプリケーション全体を終了するかのどちらかです。

私は別のスレッドからの接続でCloseを呼び出してみましたが、これは連続的にブロックされているようです。私もトランザクションをロールバックしようとしましたが、これは同じ問題を呈します。

唯一の解決策は、別のプロセス(または多分アプリドメインですか?)でクエリを実行することです。

私は明らかに何かが不足している可能性が高い、どんな助けも大歓迎です。

この質問はusing文の中で私の接続をラップに関するものではありませんお読みください。 は、閉じるために問合せを実行しているOracle接続を強制的に実行する方法です。

例:

  • スタートクエリを実行しているスレッド
  • スタッシュ接続オブジェクトのどこかに
  • 近い接続オブジェクト

    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.Cプロシージャの実行を待っているブロックを失う。

+0

のOracleプロバイダをADO.NETあなたはどちらを使用していますか?(マイクロソフトは、非同期処理をサポートしていないので、別の接続で接続して問題のプロセスを停止するコードを記述する必要があるかもしれません)。 – driis

+0

11.2.0に付属するOracle.DataAccessプロバイダです。 – jonnii

+1

よくある質問です。明らかに、最初にクエリを中止する必要があります。この電車の動きをどのように設定するかを説明するまで、答えは得られません。「レポートウィンドウ」は無意味です。郵便番号。 –

答えて

2

私は、進行中のクエリを中止またはキャンセルするAPIには何も表示されません。技術的には、完全な特権を持つ2番目のセッションで、中止したいセッションを特定し、そのセッションでkill sessionコマンドを発行することができます。私はあなたの元のセッションが何らかの例外で救済されることを期待していますが、私はそれを試したことはありません。

Hereセッションを強制終了する方法が説明されています。

HereセッションIDを取得する方法が回答されています。あなたは長時間実行しているクエリを開始する前にそれを見つけることができます。そして、2番目の接続からそのセッションを正確に殺すのはかなり簡単です。

は、それが動作するかどうか、私たちを知ってみましょう;)

+0

良いアイデア、私はDBAを過ぎてこれを実行し、彼らがそれを実行するかどうかを見てください。私はそれが、発呼信任状に飛行しないかもしれないシステムを変更する能力を与えることを意味すると思います。 – jonnii

+0

あなたは別のユーザーを使用してキルセッションを行うことができますが、同じアカウントである必要はありません。 – flq

+1

私はこれをホイップして、素晴らしい動作をします、これは正しい方向に私を指摘しました。私は 'sid、serial#from v $ sessionからaudsid = sys_context( 'userenv'、 'sessionid')'とそれに続く 'システムを変更するセッション(sid、session)を即座に変更'を実行しています。クエリ。 – jonnii

0

.NETで、プロバイダーと同じように、あなたは、だから、あなたがする必要があるすべてであるDispose

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

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

を呼び出すことができます。

+0

接続を開いて現在クエリを実行しているスレッドが45分間ブロックされている場合、クローズまたはディスポーザルを実行するにはどうすればよいですか? – jonnii

+0

私はOracleデータベースでの経験は限られていますが、45分間はクエリがブロックされていないことがわかります。あなたがあなたのコードを意味することができない場合、あなたが接続を開く方法を投稿した場合、それは接続を閉じることができるはずです。 –

+0

すべてのクエリが45分かかるわけではありませんが、大部分が数秒で実行されますが、結果セットを減らすためにパラメータを指定する必要があります。 – jonnii

1

誰が誰をブロックしているもの/参照するには、次の

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; 
関連する問題