3

複数のスレッドで同時にOpen()複数の を実行する際に問題があります。OracleConnection

シングル スレッドの例であるExample Aは正常に動作します。

for (int i = 0; i < 100; i++)
{
    OracleConnection oracon = new OracleConnection(oraconstr);
    oracon.Open();
}

(この問題に遭遇した実際の例を取り除こうとしているので、ここでは意図的に接続を閉じていません)

を使用netstatして Oracle サーバーへの実際の TCP 接続の数を確認すると、実際に 100 の接続が確立され、ループが終了した後にアクティブになっていることが確認されます。

例 Bは同じことを行いますが、複数のスレッドのみを使用します。

for (int i = 0; i < 100; i++)
{
    ThreadPool.QueueUserWorkItem(
        state =>
        {
            OracleConnection oracon = new OracleConnection(oraconstr);
            oracon.Open();
        });
    // Thread.Sleep(100);
}

マルチスレッドの場合、アクティブな TCP 接続が 1 つだけnetstat表示されます。「Open() レース」に勝った幸運な最初のスレッドを除いて、他のすべてのスレッドは への呼び出しでブロックされ、15秒後に接続が切断されます。タイムアウト、odp.net が最終的にスローされますOpen()

Oracle.DataAccess.Client.OracleException Connection request timed out

また、このネイティブな例外スローします。これにより、アプリが実際にクラッシュします。

ORA-24550: signal received: Unhandled exception: Code=e0434f4d Flags=1

kpedbg_dmp_stack()+428<-kpeDbgCrash()+102<-kpeDbgSignalHandler()+123<-skgesig_Win_UnhandledExceptionFilter()+173<-0000000077A49380<-0000000077B6573C<-0000000077AE5148<-0000000077B0554D<-0000
000077AE5D1C<-0000000077AE62EE<-000007FEFDD7AA7D<-000007FEE7E6F0BD<-000007FEE8422ED0<-000007FF001AB805<-000000000268A4B8<-00000000FFFFFC18

Thread.Sleep上記のステートメントでコメントすれば、すべて問題ありません。50ms を試しましたが、十分ではありませんでした。念のため、すべての前に 100 ミリ秒のスリープを実行するOracleConnection.Open()ことは、明らかにパフォーマンスの高いソリューションではありません。

ここで何が起こっているのか、これを修正または回避する方法はありますか? (もちろん、この質問を投稿したら、オラクルと直接話をする以外に)

これは、Oracle.DataAccess.dll バージョン 2.112.1.0 を使用する .net 3.5 です。2.112.3.0 もテストしました - 同じ結果です。

Fwiw、Google によると、このような同じ .net 例外を持つ他の人がいて、関連している可能性があります。

4

0 に答える 0