41

SqlConnection オブジェクトをインスタンス化すると、実際には接続プールから接続を取得していることを理解しています。Open() を呼び出すと、接続が開かれます。その SqlConnection オブジェクトで Close() または Dispose() メソッドを呼び出すと、接続プールに返されます。

ただし、それが本当に閉じているかどうか、またはデータベースへのアクティブな接続がまだあるかどうかはわかりません。

SqlConnection をネットワーク レベルで強制的に閉じるにはどうすればよいですか、または少なくともいつ閉じるかを伝えるにはどうすればよいですか?

例:

using(SqlConnection conn = new SqlConnection(DBConnString)) {

   conn.Open();
   SqlCommand cmd = conn.CreateCommand();
   ...
   cmd.ExecuteReader(CommandBehavior.CloseConnection);
   ...
}
  • 最初の実行: 300 ミリ秒
  • 2 回目の実行: 100 ミリ秒
  • 3 回目の実行: 100 ミリ秒
  • 長時間(30分)待った後:300ミリ秒

接続が本当に閉じていた場合、2 回目と 3 回目の実行も 300 ミリ秒になるはずです。しかし、これらの実行では接続が完全に閉じられていないことがわかっています (SQL Server のアクティビティ モニターを確認しました)。認証などを実行するのに余分な 200 ミリ秒はかかりません。

接続を強制的に閉じるにはどうすればよいですか?

アイデア

  • CommandBehavior.CloseConnection は機能しますか? (どうやらそうではない?)
  • 接続文字列で「最大プール サイズ = 0」を設定しても機能しますか? (これはピュロス溶液になります)
  • Dispose() は機能しますか?

参考文献

4

7 に答える 7

55

たぶんSqlConnection.ClearPool

于 2009-07-17T23:38:17.867 に答える
26

Moe Sisko の答え (Call SqlConnection.ClearPool) は正しいです。

プールに戻るのではなく、実際に接続を閉じる必要がある場合があります。例として、スクラッチ データベースを作成し、スキーマを構築し、いくつかのテストを行い、すべてのテストに合格した場合にスクラッチ データベースを削除する単体テストがあります。

接続プーリングがアクティブな場合、まだアクティブな接続があるため、drop database コマンドは失敗します。プログラマーの観点から見ると、すべての SQLConnection は閉じられていますが、プールはまだ 1 つ開いたままになっているため、SQL Server はドロップを許可しません。

接続プーリングの処理方法に関する最適なドキュメントは、MSDNの SQL Server 接続プーリングに関するこのページです。オープンとクローズを繰り返すことでパフォーマンスが向上するため、接続プールを完全にオフにすることは望ましくありませんが、データベースを解放するために SQLConnection で「強制クローズ」を呼び出す必要がある場合があります。

これは ClearPool で行われます。SqlConnection.ClearPool(connection)閉じる/破棄する前に呼び出すと、閉じる/破棄すると本当に消えます。

于 2010-02-03T18:45:34.603 に答える
14

接続プールを使用したくない場合は、SqlConnection.ConnectionStringプロパティで指定する必要があります。例えば

"Data Source=MSSQL1;Database=AdventureWorks;Integrated Security=true;Pooling=false;"

オブジェクトを破棄または閉じるSqlConnectionと、接続が閉じられ、接続プールに返されます。

于 2009-07-17T22:46:13.697 に答える
3

一般に、接続プールにその仕事をさせたい - 接続を完全に閉じる必要はありません。

接続がプールに戻らないようにする具体的な理由は何ですか?

于 2009-07-17T23:49:23.490 に答える
-1

CommandBehavior.CloseConnectionこの事実のために、通常は落胆します-接続が閉じられるかどうか確信が持てません。(私はこれのいくつかの具体的な証拠を見つけようとします、私はかすかな思い出からこれを言っています).

Dispose()を暗黙的に呼び出すため、最も確実なClose()方法です。

@Alexによって示される構造は、オブジェクトの暗黙的な破棄を追加しusingて構造を記述する別の (プログラマーフレンドリーな) 方法です。try-finally

編集:(質問への編集後)

接続が実際に閉じているというあなたの懸念は、私には不当に思えます。接続は単純にプールに戻されるため、すべての初期化を行うことなく簡単に再利用できます。これは、接続がまだアクティブに DB に接続されているという意味ではありません。

于 2009-07-17T22:26:59.147 に答える
-2

ロバートの答えは、SqlConnection.ClearPool(TheSqlConn)まさに私が望んでいたことでした。必要に応じてプールを操作できることを知っておくと便利です。

私のユースケースは次のとおりです。接続を台無しにしてプールに戻します。接続が台無しになったことを検出して更新する方法で、次のユーザーに問題が発生しないようにします。

解決策は次のとおりです。接続を台無しにしたことを検出し、プールから完全にクリアして、プールが新しい接続で満たされるようにします。

SqlClient.SqlConnection を 10 年間書いてきましたが、今日までプールとやり取りすることなど考えたこともありませんでした。

于 2016-11-01T11:44:29.990 に答える