2

私はスレッドプールを使用して、重い処理と少しのSQLを実行しています。現在、必要なときにSQL接続を開き、クエリを実行してから閉じます。これはうまくいきます。アプリケーションは問題なく実行されています。このアプリケーションは、より多くの作業を行うため、より多くのスレッドを使用しています。より多くのスレッドは、より多くの SQL 接続の開閉を意味します。SQL 2005 では、これは実際にサーバーに打撃を与えます。私のテスト サーバーは、1 秒あたり約 175 トランザクションを実行しています。これらのうち約 150 が master データベースで実行されており、「ValidateSQLLogin」です。

各スレッドに独自の接続があり、この接続がスレッド全体に渡されるようにアプリを変更します。

だから私の質問は:

SQL 接続オブジェクトがスレッド内でローカルに作成され、ref によって別のクラスの静的関数に渡される場合、これは安全ではありませんか?

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接続の開閉を最小限に抑える必要があります。

ありがとう

ガレス

4

6 に答える 6

5

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

于 2009-03-13T12:17:50.657 に答える
2

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

SqlConnectionただし、参照によってメソッドに渡す理由はありません。

于 2009-03-13T12:23:14.577 に答える
0

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

于 2009-03-13T13:02:12.610 に答える
0

次のことを試してください。

lockステートメントを使用して、この接続を使用しているコード ブロックに他のスレッドが入るのを防ぐことができます。他のスレッドは、前のスレッドが完了するまで自動的に待機してから、このセグメントに入ることができます。ロックしているオブジェクトが静的クラスに対してプライベートであることを確認してください。

于 2009-03-13T13:12:42.507 に答える
0

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

  • 例外: 一部の値型は、アクセス/書き込みにアトミック操作を使用し、それらの操作に対して暗黙的にスレッドセーフです。ただし、これらを取得および更新するロジックでは、依然として競合状態が発生する可能性があります。
于 2009-03-13T12:32:37.923 に答える