comment今年は基本的なことをきちんと見直していこうかと。しては以下のようなものがあります。(Transact-SQL)■コネクション最初に、以下のようなスクリプトを実行した場合に、各状態がどのようになるかを見てみたいと思います。@@VERSION」を実行して表示するものとなります。上記のスクリプトでは「ApplicationName」として「PoshSQLTest-01」を指定していますので、以下のようなクエリを実行することで、上記のスクリプトのコネクションとセッションの情報を確認することができます。bys.session_id今回は、シンプルなクエリの実行方法ですので、以下のような状態となっていることを確認することができます。使用して接続が行われているスクリプトを複数同時に実行した場合は以下のようになります。使用されていますがクライアントのポートに関しては複数が使用されていることが確認できますね。コネクションにはいくつかの上限がありますので、これについても見ていきたいと思います。(サーバー側の接続数上限)一つがサーバー側の接続数の上限となります。あれば、デフォルトの設定は同時接続は無制限となっていますが、サーバー側でコネクションの上限を設定することも可能です。場合は、パフォーマンスレベルに応じて変わってきます。リソース制限パフォーマンスレベルに応じてコネクションとセッションの上限が決まっており、この節の内容はコネクションの上限と関連がある内容となります。サーバー側のコネクションの設定の上限に達している接続がすでに行われている場合、新規の接続を完了することができなくなります。以下は一例ですが、接続数の上限に達している状態で接続を行おうとした場合は以下のようなエラーが発生します。接続上限のエラーとなります。サーバーとの接続を正常に確立しましたが、ログイン前のハンドシェイク中にエラーが発生しました。指定されたネットワーク名は利用できません。assistance.このようなエラーが発生している場合は、サーバーで許容できる接続の数が枯渇している状態になっていると判断することができるかと。コネクションプールについて以下の情報が参考になります。「タイムアウトに達しました。プールから接続を取得する前にタイムアウト期間が過ぎました。サイズの制限値に達した可能性があります。コネクションプールでは一度開かれたコネクションを、一定の期間プールとして維持します。実行しても、接続はプールに返却がされる動作となり、バックグラウンドは接続中の状態となるため、プールが破棄されるまでは、実際の接続の解放は行われていない状態となります。以下のように記載されています。接続プールは、新しく開く必要のある接続の数を減らします。プーラーには、物理的な接続の所有権が保持されます。プーラーは、任意の接続構成それぞれのアクティブな接続のセットをそのまま保持して、接続を管理します。呼び出すと、プーラーは、プールに使用可能な接続があるかどうかを確認します。プールされた接続が使用できる場合は、新しい接続を開く代わりに、プールされた接続を呼び出し元に返します。呼び出すと、プーラーは接続を閉じる代わりに、プールされたアクティブな接続のセットに接続を返します。呼び出しで再度使用できる状態になります。コネクションプールはデフォルトでは有効な状態になっています。そのため、先ほどのスクリプトの実行が完了しても一定の期間は、コネクションプールにより接続が行われた状態となっています。$falseを追加して実行してみると違いが判るかと思います。コネクションプールが有効な場合、スクリプトの実行が完了しても一定期間はコネクションが残った状態となります。「Pooling」を「false」に設定することでコネクションプールが無効となり、クローズ時に接続が解放される動作となりますので、スクリプトの実行が完了した後に、コネクションの状態を確認するクエリを実行してみると、コネクションがなくなっていることが確認できます。解放についてはコストが高いと言われているかと思います。コネクションプールは一度作成したコネクションを再利用することで上記のコストを緩和させるための仕組みですので、通常はコネクションプールを無効にすることはないかと思いますが、動作の違いについては覚えておいた方がよいかと。コネクションプールからコネクションを解放するための動作として、以下のように記載されています。分になったか、サーバーとの接続が切断されたことをプール機能が検出した場合に、プールからの接続を削除します。サーバーとの通信を試みた後にのみ、切断されたサーバー接続が検出可能になることに注意してください。接続がサーバーに接続していないことがわかると、その接続は無効としてマークされます。無効な接続は、閉じられるか、または再利用された場合のみ、接続プールから削除されます。存在しないサーバーへの接続が存在する場合は、接続プーラーが、その接続が切断されていることをまだ検出せず、無効というマークを付けていない状況のときでも、プールからその接続を削除できます。トリップが実行されることにより、プーラーの利点が失われてしまうことを防ぐためにあります。この状況が発生した場合は、接続の使用を最初に試みたときに接続が切断されていることが検出され、例外がスローされます。基本的にはプール側の動作にお任せする感じとはなります。可用性グループで以下のような動作を行ってみます。ついては、特筆すべき動作はありません。実行した際には以下のようなエラーとなることがあります。レベルのエラーが発生しました。セマフォがタイムアウトしました。フェールオーバーしたタイミングで、接続元の実体が変わりますが、コネクションプールではフェールオーバー前のサーバーに対して接続が行われています。実行したタイミングで成功をするケースがあります。フェールオーバー直後に再接続を行った場合などは、上記のケースに該当するかと思います。時間をおいてから、スクリプトを実行した場合はエラーは発生しないかと思いますので、フェールオーバー直後の接続のリトライについては意識をしておいた方がよいかもしれないですね。以下のような機能が追加されています。つの新しいメソッドが導入されました。特定の接続に関連付けられた接続プールをクリアします。これらのメソッドが呼び出されたときに使用中の接続がある場合は、適切にマーク付けされ、接続が閉じられるとプールに返されずに破棄されます。以下のような方法で、コネクションプールの明示的なクリアを実施できるようになっていますので、検証時などにプールに接続のあり/なしを意識する必要がある場合は、明示的なクリアを検討してもよいかと。接続をコネクションプールとしてプールできる形となります。以下のパラメーターで実行してみます。fl$sw.Stop()上記のパラメーターで実行した際のスクリプトからの接続数は「100」となっています。秒待機するようなクエリを実行しています。接続が行われた状態となります。側の接続数の設定範囲内であれば、接続を行うことができます。設定されたコネクションプールの確保待ちの状態となり、確保待ちが続くとコネクションプールの確保に関してのタイムアウトとなります。タイムアウトに達しました。プールから接続を取得する前にタイムアウト期間が過ぎました。サイズの制限値に達した可能性があります。以下の記述の動作ですね。接続プーラーは、接続がプールに解放されたときに接続の再割り当てを行って、接続に対する要求に応えます。サイズに達すると、使用可能な接続を取得できなくなり、要求はキューに置かれます。達するまで接続の再利用を試みます。接続がタイムアウトになる前に、プーラーが要求を満たすことができない場合は、例外がスローされます。この状態になった場合は、コネクションプールの上限を変更するか、各接続で実行されているクエリが短時間で終了するようにして、コネクションが再利用できるようにします。接続元のコネクションプールの数を考慮して、何接続が行われるかの検討が必要になってくるかと。最後に、コネクションプールの利用状況を確認してみたいと思います。SqlServer」を使用して接続を行っています。情報を確認することで、コネクションプールがどの程度利用されているのかを確認することができます。この辺は接続に使用しているライブラリに応じて取得方法が変わってくるかと思いますが。接続が同時の行われた状態のコネクションプールの状態となります。コネクションあることが確認できますね。コネクションプールは接続文字列単位となるため、上記の状態から接続文字列を一部変更して接続を行うと以下のような状態となります。(使用している接続文字列の数の判断に使えるかもしれませんね)、プール内のコネクションの数を「NumberOfPooledConnections」から確認することができます。認証を使用して接続を行っている場合は、ユーザー単位にプールが作成されるようですので、接続の方式がプールの数が変化する要因になるというのも意識をしておいた方がよさそうですね。基づいてプールされます。つのプールが作成されます。これによって、単一のユーザーによる後続のデータベース要求のパフォーマンスが向上しますが、他のユーザーによって作成された接続は使用できません。サーバーに存在することになります。アプリケーションのアーキテクチャに重点を置く必要があるために起こる副作用です■セッション上記では、一接続が一セッションとなるようなシンプルな実行を行っていました。使用すると、単一の接続を利用して、複数のセッションを使用することができるようになります。単純なスクリプトとしては以下のようなものとなるでしょうか。$rs2[0]$con.Close()$con.Dispose()実行後に、以下のクエリで情報を取得してみます。bys.session_id親となる接続を一つ持ち、その接続を利用した複数のセッションが設定されているという状態が確認できます。この時のポートの利用状況ですが、各セッションはサーバー/クライアントともに接続に使用したポートを利用しているため、一つのコネクションを複数のセッションで利用している状態となっているかと思います。実行してみたいと思います。この時の状態を以下のクエリで取得してみます。bynet_transportこのような実行形態の場合は、一接続から複数のセッションが使用された状態となります。セッションが存在していることが確認できますね。接続が利用できた形となります。コネクションとセッションは別で管理されていることがこの情報から確認することができるかと思います。この情報から、接続数の上限はセッションではなくコネクション側で効いていることが確認できるかと。有効でない場合は以下のような結果となります。この場合は、コネクション内のセッションで処理が完結するイメージでしょうか。作成されているようで、単純に「MultipleActiveResultSets」を有効にしただけでもこのような動作の違いは出てくるようです。接続数の上限がある場合、一つの接続の中で複数のセッションを使用したクエリ実行というのは、接続の上限がある中での複数クエリを実行する方法として、覚えておいた方がよいのかもしれないですね。待ちが発生することがあるそうなので、ここも意識しておく必要がありそうです。コネクションだけでなくセッションの上限も決まっているため、セッション数についても意識をしておく必要があるかと思います。はじめとした各種ビューの関連性があらわされた資料が公開されています。多の関係となっていることが確認できます。複数というようなイメージを持ってしまうかもしれないですね。基本的なことをきちんと理解しないとなと思った今日この頃です。チューニング等をメインにしていますが、本ブログで情報発信している内容に関することでしたら対応できます。お仕事のご相談がありましたらTwitterfacebookやブログのコメントでご連絡いただけると幸いです。ブログにコメント頂いた内容は私が承認しない限り表示されません。受賞させていただきました。本ブログの内容は個人的に検証したものとなり、検証結果を含め記載している内容を保証するものではありません。体験記の連載をさせていただきました。最後まで飲み切れず...。