web-dev-qa-db-ja.com

接続プーリングの使用中にSqlConnectionを強制的に物理的に閉じる方法は?

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分)待った後:300ms

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

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

アイデア

  • CommandBehavior.CloseConnectionは機能しますか? (どうやらそうではない?)
  • 接続文字列で「最大プールサイズ= 0」の設定は機能しますか? (これは根本的な解決策になります)
  • Dispose()は機能しますか?

参照

40
52
Moe Sisko

Moe Siskoの回答(Call _SqlConnection.ClearPool_)は正しいです。

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

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

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

これはClearPoolで行われます。閉じる/破棄する前にSqlConnection.ClearPool(connection)を呼び出した場合、閉じる/破棄を行うと、実際になくなります。

25
Robert Calhoun

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

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

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

9
ZippyV

一般的には、接続プールにその仕事をさせたいと思います-接続を本当に閉じたくないです。

具体的には、接続がプールに戻らないようにしたいのはなぜですか?

2
Eamon Nerbonne