最近、asp.netとSQLServerのサイトに基づいてプロジェクトを行うと、いくつかの時間のために実行した後にサイトを見つけ、例外が報告されます。
タイムアウトの有効期限が切れますが、プールから接続を取得します。これは、すべてのプールされた接続が使用中であったため発生した可能性があると最大プールサイズに達しました
この明らかな異常がSQLServerデータベース接続プールでコードがDBリンクを解除される場合忘れていると推定、既定のサイズを超えています。
調査とデータアクセス層のコードは今DBHelperある、だから今解決しました。
何かをまとめ、それを記録。
DBHelperAコード:
パブリック クラスDBHelperA { 公共の 文字列 connStr = 「あなたのSQLServerデータベース接続」。 公共のIDbConnection _conn。 公共のIDbConnectionコネティカット { 取得する { もし(_conn == nullの) { _conn = 新しいSqlConnectionオブジェクト(connStr)。 } 返す_conn; } } }
ClassAクラスコード:
パブリック クラスにClassA:DBHelperA { 公共 のボイドDoItFirst() { 使用して(コネチカット州) { もし(Conn.State == ConnectionState.Closed) { Conn.Open(); Console.WriteLineを(Conn.GetHashCode())。 } } } 公共 のボイドDoItSecond() { 使用して(コネチカット州) { もし(Conn.State == ConnectionState.Closed) { Conn.Open(); Console.WriteLineを(Conn.GetHashCode())。 } } } }
ClassAは、オブジェクトを作成し、2つのメソッドを呼び出します。
パブリック 静的 ボイドTESTA() { 用(int型 i = 1 ; iが< 200 ; iが++ ) { ClassAのA = 新にClassA(); a.DoItFirst(); a.DoItSecond(); Console.WriteLineを(I); } Console.ReadLine(); }
一見何も問題のコードよりも多くが、実行時に、それは意志()メソッドは、a.DoItSecondに例外をスロー:のConnectionStringプロパティが初期化されていません
コネティカットは、オブジェクトによって占有声明解放されたリソースを使用して、DoItFirst()メソッドを実行しますが、後のオブジェクトconnが、これは、空ではありません
ないDoItSecond()メソッドを実行するときしたがって、connオブジェクトを再作成します。また、異常発生で、その結果、データベース接続を開くためにコネチカットのリソースを解放されたオブジェクトを使用するためのリード
DBHelperBコード:
パブリック クラスDBHelperB { 公共の 文字列 connStr = 「あなたのSQLServerデータベース接続」。 公共のIDbConnectionコネティカット { 取得する { VaRの CONN = 新しいSqlConnectionオブジェクト(connStr)。 Console.WriteLineを(conn.GetHashCode())。 返すCONN; } } }
ClassBのコード:
パブリック クラスClassBの:DBHelperB { 公共 のボイドドイト() { 使用して(コネチカット州) { もし(Conn.State == ConnectionState.Closed) { Conn.Open(); Console.WriteLineを(Conn.GetHashCode())。 } } } }
ClassBのオブジェクトを作成し、メソッドを呼び出します。
公共の 静的な 無効TESTB() { 用(int型 i = 1 ; iが< 200 ; iが++ ) { ClassBののB = 新しいClassBの()。 b.DoIt(); Console.WriteLineを(I); } Console.ReadLine(); }
実行は例外をスローします。
ビューのこの時点で、データベースセッションの接続は100台の接続が見つかりました:
これは、多くの接続を作成したドイトメソッドは、オブジェクトコネティカットへの参照は、開いて使用して、新しい接続を返すと声明を発表するたびにデータベースで、その結果、同じCONNオブジェクトではないためであります
DBHelperCコード:
パブリック クラスDBHelperC { 公共の 文字列 connStr = 「あなたのSQLServerデータベース接続」。 }
クラスCコード:
公共 のボイドドイト() { 使用して(VARコン= 新しいSqlConnectionオブジェクト(connStr)) { もし(Conn.State == ConnectionState.Closed) { Conn.Open(); Console.WriteLineを(Conn.GetHashCode())。 } } }
クラスCのオブジェクトを作成し、メソッドを呼び出します。
公共の 静的な 無効TESTC() { 用(int型 i = 1 ; iが< 200 ; iが++ ) { クラスC、C = 新しいクラスC(); c.DoIt(); Console.WriteLineを(I); } Console.ReadLine(); }
コードを実行し、任意の異常を報告しません。そして、データベースと一つだけのセッション
各オブジェクトは、内部の文の片を使用して作成し、同じオブジェクトのリリースを使用して接続を作成することであるため。
れたconnectionStringデータベースプーリング・パラメータが指定されていないため、また、デフォルトでは、接続プールを有効にすることです。
だから、C#コードの接続オブジェクトは、オブジェクトのSQLServerデータベースに影響を与えずに作成および破棄されます。
すべてのコードは、接続オブジェクトを作成し、最初の時間を構成するためのopen()メソッドを呼び出して、データベースは、接続プールセッションのために使用されます
今、私は偽の接続プーリングに文字列を入れます
最初のループ、データベースセッションの作成時間
usingステートメントのうち最初のサイクルの後、セッションがなくなって
第二サイクルは、再び新しいDBセッションを作成しました
要約すると:
建設DBHelperクラスとデータベースアクセス層場合は、接続オブジェクトを解放するために注意を払う必要があります。それ以外の場合は、データベースの無効なセッションの束につながります
ここでのコードは、(その上に独自のデータベースのSQLServerアドレスへのデータベース接続を)試すことができます興味を持っています: