2009-03-13 11 views
2

スレッドプールを使用して、重い処理やSQLのビットを使用しています。現在、必要なときにSQL接続を開き、クエリを実行して閉じます。これは正常に動作します。アプリケーションは問題なく実行されています。このアプリケーションでより多くの作業が行われているので、より多くのスレッドを使用しています。より多くのスレッドは、SQL接続のより多くの開閉を意味します。 SQL 2005では、これは実際にサーバーをハンマーします。私のテストサーバーは約175トランザクション/秒をしています。これらのうち約150個がmasterデータベースで実行されており、 "ValidateSQLLogin"です。スレッドセーフについての質問

私は、各スレッドが独自の接続を持つようにアプリケーションを変更し、この接続がスレッドの周りを渡されるようにします。

だから私の質問は次のとおりです。

SQL接続オブジェクトがスレッドでローカルに作成され、その後、別のクラスの静的関数に参照によって渡される場合、これは安全ではないでしょうか?

void ThreadA() 
{ 
    SqlConnection a = new SqlConnection(....); 
    MyStaticClass.DoStuff(ref a); 
} 

void ThreadB() 
{ 
    SqlConnection b = new SqlConnection(....); 
    MyStaticClass.DoStuff(ref b); 
} 

static void MyStaticClass.DoStuff(ref SqlConnection sql) 
{ 
    // Do stuff with sql 
} 

私の最初に考えたのは10件のスレッドがすべてそれぞれ独自の接続オブジェクトを渡し、同時に同じ静的関数を呼び出すことができますよう、それは安全ではないだろうということです。

これまでは、静的関数は独自の接続を開いて、完了した時点で閉じました。

安全でない場合は、これを処理する最善の方法は何ですか? SQL接続のオープン/クローズを最小限に抑えようとする必要があります。

おかげ

ガレス

答えて

5

静的関数のパラメータは、静的フィールドと同じではありません。静的関数の各実行は、接続の異なるコピーを使用します。参照としてパラメータを持つ必要はありません(参照パラメータは変更したい場合にのみ必要です)。

+1

同じ接続を共有すると、次のような質問が表示されます。接続が無効な場合は、その接続を回復する方法は? – lsalamon

2

各スレッドには独自のスタックがあり、パラメータとローカル変数はスタックに格納されるため、複数のスレッドで同じ静的メソッドを呼び出すことは問題ありません。各メソッド呼び出しには、独自のパラメータとローカル変数があります。

SqlConnectionをこのメソッドに渡す理由はありません。

0

他の人によると、複数のスレッドから静的メソッドを呼び出すこと自体危険ではありません。しかし、静的メソッドが渡すパラメータで作業するのではなく、静的フィールド*を変更またはアクセスする場合は、スレッドセーフにする必要があります。

  • 例外:一部の値型では、アクセス/書き込みにアトミック操作が使用され、これらの操作に対して暗黙的にスレッドセーフです。ただし、これらを取得して更新するロジックで競合状態が発生することがあります。
-2

.Netすべての静的メンバーはスレッドセーフです。

0

このようなトランザクションの負荷がある場合は、1つの静的接続を維持することをお勧めします。このトランザクションがある間は開いたままであり、負荷が大幅に減少するか、nullの場合は自動的に閉じられ、再び。

0

次のことを試してください:あなたは、この接続を使用しているコードブロックに入ることから、他のスレッドを防ぐためにlockステートメントを使用することができ

、他のスレッドが前のスレッドが実行されるまで自動的に待機した後、これを入力していますセグメント。ロックしているオブジェクトが静的クラスのプライベートであることを確認してください。