2017-11-23 20 views
0

連続して実行されているプログラムを使用して接続に問題があります。この問題は、多くのクエリ(4分ごとに5x(3つのテーブルをクエリし、結果を1つに保存する))をタスクのDBに渡しているときに発生します。接続プールの最大プール接続サイズが不足しています。この特定の接続文字列/マシン/ユーザーエントリのためにCOMMANDエントリを待っているDB 100について、これに関する奇妙なことがあります。私の理解は、コマンドを待つことは、この接続を再利用できることを意味するが、Tasksからのコマンドを実行すると使用可能な接続を再利用することができず、誰も待たずに、最大プール接続サイズ。連続実行アプリケーションのSQL Server接続プーリング

仮定これまで:

  1. タスクから実行しているコマンドは

  2. 接続が閉じ、なぜされていない使用可能な接続を再利用する、これは無効なものとして解釈DB?キーワードを使って閉じているようだ。それ以上のことは、DBの1つのコマンドを待っています。

  3. ハンドラは何らかの理由でガベージコレクションされませんか?しかし100 ACはsth elseを伝えています。

UPDATE: LOCALDB観測/ SUMMARY:

私は非常に厄介な状況で起こるローカルDB SQL Server Expressでこの問題を、これを複製しようとしています。私は種をシミュレートする状況にThread.Sleep(600000)を追加しなければならなかった。そして結局、私は最大プールエラーを得ることができましたが、この場合はすべての接続が開いているので、それはむしろ自明です。

ローカル - >サーバーのシナリオでは、一度に100の接続を開くことはできないと思うので、何らかの理由でオープンになっています。 localMachine - > serverDBの状況でこのプログラムを起動すると、プログラムをクラッシュさせるためにThread.Sleep(600000)を追加する必要はありません。

これらはすべて私の前提です。私は4分ごとにDBを照会する私の継続的な実行中のサービスで何が起こっているのか考えることはできません。

PS。私の完全なローカルテストの後、COMMAND AWAITINGがこの接続を再利用できるという意味なら混乱しますか?

UPDATE 2私の最初のプログラムは、この最大プールエラーに遭遇する数日前に実行することができます。私はあなたのコードをデバッグし、何の接続リークを発見した

using System; 
using System.Data.SqlClient; 
using System.Threading; 
using System.Threading.Tasks; 

namespace Pooling 
{ 
    class Program 
    { 
     private static int connectionIterations; 

     private static string connectionString = "Data Source=localhost;Initial Catalog=localDB;Integrated Security=True"; 

    static void Main(string[] args) 
    { 
     try 
     { 
      Iterations(); 

      while(true) 
      { 
       ConnectionSnowball(); 
      } 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e); 
      throw; 
     } 
    } 

    private static void ConnectionSnowball() 
    { 
     Parallel.For(0, connectionIterations, i => 
     { 
      try 
      { 
       Console.WriteLine($"Connection id: {i}"); 
       using (SqlConnection connection = new SqlConnection(connectionString)) 
       { 
        SqlCommand cmd = new SqlCommand("SELECT 1 FROM test_table", connection); 
        connection.Open(); 
        cmd.ExecuteNonQuery(); 
        Thread.Sleep(600000); 
       } 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine(e); 
       throw; 
      } 
     }); 
    } 

    private static void Iterations() 
    { 
     connectionIterations = 200; 
    } 
} 
} 
+3

リソースが不足している/廃棄しているようです。あなたはSqlCommandの周りで 'using'を試しましたか? –

+0

クエリの持続時間によっては、200のconnectionIterationsが100を超える可能性があります。 –

+0

接続がプールにあり、使用可能になっているか、クライアントが使用していて現在はコマンドを提供していない場合は、サーバーから見て分かりません。その情報はクライアント側にのみ存在します。物理的な接続が未配置の 'SqlConnection'インスタンスによって使用されている限り、それは使用中です。それ以外の場合はそうではありません。クライアント上でリソースリークが発生していないかどうかを確認するには、ダンプファイルを作成し、 'SqlConnection'インスタンスとGCルートをヒープで解析して解析します。 –

答えて

0

:以下

は、この種の問題を発生させることができますプログラムです。接続プールがオーバーフローしているだけです。私はあなたのために2つの解決策を確認しました。

無効にプーリング接続

private static string connectionString = "Data Source=localhost;Initial Catalog=localDB;Integrated Security=True;Pooling=False"; 

増加接続プール

private static string connectionString = "Data Source=localhost;Initial Catalog=localDB;Integrated Security=True;Max Pool Size=200"; 

ConnectionSnowball()コール中と後に、あなたがこれを使用することができ、接続が増加し、前に減少しますどのようにテストするにはSQLクエリ

select count(1) from sys.dm_exec_sessions where database_id = DB_ID(N'localDB') 
接続文字列パラメータについて

詳細 SqlConnection.ConnectionString Property

他の可能な解決策はSQL jobsの使用です。多くの接続が非常にリソース集中的であるため、このタスクでは、これがより適切な解決策になります。

関連する問題