質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

  • Azure

    230questions

    Azureは、マイクロソフトのクラウド プラットフォームで、旧称は Windows Azureです。PaaSとIaaSを組み合わせることで、 コンピューティング・ストレージ・データ・ネットワーキング・アプリケーションなど多くの機能を持ちます。

  • ADO.NET

    20questions

    ADO.NETは.NET Frameworkで各種データベースへの統一された接続機能を提供するソフトウェアコンポーネントの集合です。

接続型と非接続型の違い

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 3,611

jun_i

score 8

お世話になります。

ADO.NETの接続型と非接続型の違いについて質問があります。

接続先のDB:AzureのSQL Database

私の今の解釈

・接続型
明示的にcloseするまでDBとの接続状態は続く。
明示的にcloseするか、アプリケーションが自体が終了すれば、接続は切れる。

・非接続型
クエリを発行する度に接続と切断をする。したがって、毎回自動的に接続は切れる。

そこで、本当にその解釈が正しいか、検証してみたところ、以下の結果になりました。

検証結果

・接続型で接続
①あえてcloseせず放っておいても、10分くらいすると接続が切れた。
②明示的にcloseしたとしても、すぐには接続は切れない。(10分くらいすると切れる)

・非接続型で接続
③クエリの処理が終了したとしても、すぐには接続は切れない。(10分くらいすると切れる)つまり②の場合と同じ動き。

推測していた動きと違うのは
・接続型でCloseしていなくても、しばらくしたら接続が切れた。
・非接続型でもすぐに切れるわけではなかった。
ということです。
これは、何故なのでしょうか?

接続型はバッチ処理のような連続でクエリを処理をする際に使い、それ以外の時はなるべくサーバーに負荷をかけないよう非接続型で接続する。というような使い分けで考えていたのですが、
上記の結果だけ見ると、あえて使い分ける意味があまりないように感じてしまいます。

以下、一応試したコードを示します。(例外処理などは省いています)

'VB.NET
'接続型の処理----------------------
Using connection As New SqlConnection([DBへの接続情報])
    connection.Open()
    Dim command As SqlCommand = connection.CreateCommand()    
    command.Connection = connection
    command.CommandText = [適当なselect文]
    Dim reader As SqlDataReader = command.ExecuteReader()
    ・
    ・selectした結果を読む処理
    ・
    connection.Close() 'あえてcloseしない時はこれをコメントした
End Using
'----------------------

'非接続型の処理--------------------
 Dim conn As New SqlConnection()
 Dim command As New SqlCommand()
 Dim adapter As New SqlDataAdapter()
 Dim ds As New DataSet()
 conn.ConnectionString = [DBへの接続情報]
 command.Connection = conn
 command.CommandText =  [適当なselect文]
 adapter.SelectCommand = command
 adapter.Fill(ds)
    ・
    ・selectした結果を読む処理
    ・
'----------------------


どちらもselect結果を取得することは出来ています。

また、すぐに接続が切れるわけではない。という部分は、コネクションプールか何かが関係しているのでしょうか?

以上、駄文で申し訳ありませんが、何か分かる方がおりましたら、よろしくお願いいたします。

2017.1.13追記

肝心なところが抜けていました。
接続が切れている、切れていないをどう確認したかというと、Microsoft SQL Server Management Studio上で、
sys.dm_exec_sessions と sys.dm_exec_connectionsを参照して確認しました。

また、sys.dm_exec_sessionsにはSTATUSというカラムがあり、ここは主にrunningかsleepingのどちら
かになります。
もしかしたら、これが接続が切れている切れていないという意味なのか?とも思い、検証してみました。

そうしたところ、
接続型では、上記コードの
Dim reader As SqlDataReader = command.ExecuteReader()

非接続型では
adapter.Fill(ds)
を処理している間のみrunnigになるということが分かりました。

接続型ではconnection.Close()をしてもしていなくても処理が終了すれば、sleepingになるので、ここの値の意味が、接続が切れている切れていないではないようです。(結果的に蛇足です。すみません)

また、もう一つ分かったことがあります。
昨日の質問内容で、接続型でも非接続型でもすぐには接続は切れずに、しばらくすると切れると書きました。
これは、やはりコネクションプールの設定のようです。
接続文字列でPooling=Falseとして繋げたら、接続型でも非接続型でも、処理が終了したらすぐに切断されました。

なのでまとめると、DBとの接続が切断(解除?)されたというのは、コネクションの接続のこととは、また違う部分の話なのではないのかな。と推測しています。

私が昨日から目で確認していたものは、「コネクションが接続された。切断された。」という話で、ここまでは接続型でも非接続型でも仕組みは変わらないのではないかと思っています。

接続型と非接続型の違いは、コネクションを繋げた後の実際にデータにアクセスする時の動作のことかと思っているのですが、ここら辺について詳しい方いたら教えていただきたいと思います。

長文失礼いたしました。よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

0

最初に、
つなげたままなのに勝手に切れるのは、
https://msdn.microsoft.com/ja-jp/library/8xx3tyca(v=vs.110).aspx
の「接続の削除」あたりの内容の話なのかなと感じています。

コネクションプールについてはおおよそご理解のとおりかと思います。

以降、私の理解・考えなので、100%正しいわけではない前提で見ていただきたいのですが、

本題の接続型と非接続型については、ただの概念だと思っています。
このクラス(またはメソッド)を使えば使えば非接続型、あっちを使えば接続型という話ではないと思っています。

コードサンプル付きのやつがここら辺にありますが、こんな感じなら接続型/非接続型に実装できるだけの話だと思っています。
https://msdn.microsoft.com/ja-jp/library/cc482903.aspx

ただ、もはやC#界隈でDataSetなんて使う人もいない(と個人的には思っている)し、
ここ数年の流れだと、
ADO.NETを使った上記の接続型っぽいコードで、Modelとなるオブジェクト(.NETでいえばPOCO的なもの)を操作しつつ、ドメインのModelとなるものと変換をしたりて、もちろん非接続型のプログラミングするのが一般的かなーと、私は理解しています。

具体的には、Repositoryパターン的なクラスでDBContextや接続周辺だったりUnit of Workあたりをラップしてあげて...ビジネスロジックとなるServiceのレイヤーでViewModelにしてってやつですね。

(githubとかその他諸々でコードを見たり、自身で構築してきてそう理解しています...)

コネクションプールについてちょっと書いておくと、サーバーサイドからDBへの接続で最もコストのかかるのが、ゼロからDBにアクセスするところです。それを毎回切断しては接続してはパフォーマンスが悪いため、コネクションをプールしておきコストを下げています。

プログラムでいうところの接続/切断と、プールを使ってどーこーする制御は、見方次第では別な話ですが、どう効率的に使いまわすかをFrameworkだったりがやってくれているという意味では無関係ではないところになります。

実際にプログラムでDAL部分をどう構築するかは、リポジトリーパターンやUnit of Workなどで英語で検索すると、たくさん参考になりそうなものが出てきます。

ということで、回答というより個人的に理解していることを書いただけですが、お役に立てると....。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

.NETではなくC++で経験したことですが、DBへの接続にはTCPリソースを消費します。切断するとリソースはすぐには解放されません。なので、DBへの接続と切断を頻繁に繰り返すと、リソースが枯渇しそのうち接続ができなくなります。
リソースはある一定時間で解放されるので、しばらくするとまた使えるようになります。これは接続の頻度に依ります。解放時間はレジストリに書いてあるようですが、これをいじるのはおすすめできません。

なので、いらぬ不具合を出さないように、DBへの更新や書き込みが頻繁であるのなら常時接続しておいたほうが良いと思います。切断は、アプリを終了する時はもちろんですが、何らかの異常(書き込み不良など)が発生したときなどに限るようにします。

DBが同一PC内にあるような場合はこの限りではありません。サーバとしてネットワーク先にある場合です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Azure

    230questions

    Azureは、マイクロソフトのクラウド プラットフォームで、旧称は Windows Azureです。PaaSとIaaSを組み合わせることで、 コンピューティング・ストレージ・データ・ネットワーキング・アプリケーションなど多くの機能を持ちます。

  • ADO.NET

    20questions

    ADO.NETは.NET Frameworkで各種データベースへの統一された接続機能を提供するソフトウェアコンポーネントの集合です。