複数のスレッドで同時に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 例外を持つ他の人がいて、関連している可能性があります。