閉じられていないデータベース接続はどうなりますか?
-
06-07-2019 - |
質問
今日、プロジェクトの1つでバグを発見しました-閉じられないデータベースとの接続があります。つまり、Close()メソッドが呼び出されることはありません。ただし、アプリケーションを閉じると、接続が閉じられます(SQL Management Studioで何度もチェックされます)。なぜですか?
解決
アプリケーションが終了すると、接続が閉じます。 SqlConnectionのファイナライズをご覧ください。 Object.Finalize に関するMSDNのドキュメントから:
"アプリケーションドメインのシャットダウン中、ファイナライズは、ファイナライズを免除されていないオブジェクト、まだアクセス可能なオブジェクトであっても自動的に呼び出されます。
他のヒント
ここで留意すべきもう1つの点は、.Netでは、使用中のブロックで接続をラップできることです。これにより、接続が閉じられて破棄されます。したがって、使用中のブロックがある場合、明示的なClose()の欠如は悪いことではありません...
// this using block will auto close & dispose your connection...
using (var conn = new SqlConnection(...))
{
conn.Open();
// database code here with no explicit close
}
これは、finallyにconn.closeを指定したtry / finallyブロックと機能的に同等です。多くの開発者はブロックの使用を見落としています。この場合、同じことをしていないことを確認してください。
接続を閉じるようにコードを書き直す場合-データベースオブジェクト(接続、コマンド、リーダー)のすべてを囲むブロックを使用して、それらが範囲外になったときに閉じて破棄することを確認することをお勧めします使用ブロック。必要に応じてconn.Close()だけでなく、コードにそれらを書き込むことをお勧めします。
SQL接続は作成に費用がかかるため、ADO.NETは接続プーリングと呼ばれる手法を使用して再接続を可能にします。
MSDN からの引用:
次のことを強くお勧めします いつでも接続を閉じます 使い終わるように 接続プールに返され、 再利用されます。
最大プールサイズが 到達し、使用可能な接続はありません 利用可能な場合、リクエストはキューに入れられます。の プーラーはその後、 タイムアウトになるまでの接続 到達しました(デフォルトは15秒です)。 プーラーが満足できない場合 接続時間の前にリクエストする アウトすると、例外がスローされます。
通常の方法でアプリケーションを終了すると、ファイナライザーが実行されると思います。接続がまだ開いている場合、接続を閉じます。 これに依存しないでください。ファイナライザがアプリケーションの通常の操作で実行されるまでに時間がかかる場合があるため、開いている接続が多すぎます。
アプリケーションがクラッシュすると、ファイナライザが実行されず、アプリケーションの有効期間が経過しても接続が開いたままになる可能性があります。