0

マルチスレッドのC#アプリケーションがあり、各スレッドにアクティブな接続が必要です。静的接続を使用して、ロックを使用せずにマルチスレッドアプリで複数のテーブルを正確に更新/挿入する方法がない限り、接続プールを使用できません。接続数が約200の場合は、問題ありません。接続はこれを超えて成長しません。しかし、2200以上の接続が必要な場合、接続の数は無限に増え続けます。

接続を作成するためのコード-

 @"Data Source=Server-3-PC\SQLSERVER2012;Initial Catalog=****;Persist Security Info=True;User ID=****;Password=****;Pooling=false";

-を使用してSSMSからの接続を確認しています

sp_who2
4

2 に答える 2

1

開いた接続をすべて閉じるのはあなたの責任です。プーリングを使用するかどうかに関係なく、パターンは、接続を作成して開き、1つ以上のSqlCommandに使用して閉じます。

プーリングに関しては、プーリングが有効になっている接続は、閉じられる前に再利用されません。その時点で、接続は再利用される前にリセットされます。どちらの方法でも、接続を閉じる必要があります。


接続プールの使用に影響を与える複数のスレッドに関しては、それがどのように関連しているかわかりません。SqlConnectionはスレッドセーフではないため、特定の接続の所有権を単一のスレッドに割り当てるか、一度に1つのスレッドのみがそれにアクセスするようにする必要があります。いずれにせよ、完了したら閉じる限り、接続プールに問題はありません。


私は理解しており、2k接続で何が起こるかはわかりませんが、その多くの接続のオーバーヘッドが正常であるとは想像できません。データベースまたはCPUのいずれかによって制限されることになりますので、設計を再考することを検討します。おそらく、より少ない接続を許可するある種のバッファリングまたは委任。

たとえば、インバウンドEDIファイルを一度に多数処理するアプリケーションがあります。各ファイルには、データベースの更新が必要な約5万件のレコードがあります。ファイルごとに1つの接続で50,000コマンドを実行する代わりに、後で更新するためにキューに入れられる変更を生成するリーダーがあります。

リーダーが5000程度の更新を作成した後、キューはデータテーブルを作成し、それをパラメーターとしてストアドプロシージャに渡します。これにより、1回のラウンドトリップ、1回のトランザクション、および1回の接続で、多くのファイルからの5000回の更新を処理できます。1秒あたり200回の更新から1秒あたり17,000回の更新に変更しました。

于 2012-11-18T18:21:05.097 に答える
0

私は答えを見つけました。並列ループ内で接続を作成して閉じることは信頼できません。接続は常にループの外側で作成し、内側で使用し、外側で閉じる必要があります。

ご覧いただきありがとうございます。

これをよりよく説明するために、これは機能します-

 Parallel.For(0,NumSymWatching , x =>
                {
                    String conString = @"Data Source=TEJ-HP\SQLSERVER2012;Initial Catalog=DRMinutesData;Persist Security Info=True;User ID=sa;Password=sql;Pooling=false;";
                    SqlConnection hConnectionBars = new SqlConnection(conString);
                    hConnectionBars.Open();
                    SqlCommand hCommandBars = new SqlCommand();
                    hCommandBars.Connection = hConnectionBars;

                    BuildHistoricalBarData(A[x], B[x], beginFilterTimeMinutes, hCommandBars);


                    hConnectionBars.Dispose();
                    hConnectionBars = null;

                });

接続は、希望どおりに開かれ、使用され、閉じられます。ただし、BuildHistoricalBarDataメソッド内に接続を作成すると、接続は増え続けます。

ここでプーリングが使用されない理由は、「A」が異なるテーブルを指すアイテムの配列であるためです。同じテーブルであったとしても、hCommandBarsは(並列で実行されているスレッドによって)変更され、ロックを使用せずに正確な挿入/更新アクションを実行することはできません。その後、ロックはそれを遅くします。

于 2012-11-21T03:47:17.637 に答える