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

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

新規登録して質問してみよう
ただいま回答率
85.48%
ADO.NET

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

Azure

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

Q&A

2回答

16233閲覧

接続型と非接続型の違い

jun_i

総合スコア14

ADO.NET

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

Azure

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

0グッド

1クリップ

投稿2017/01/12 08:18

編集2017/01/17 03:07

お世話になります。

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との接続が切断(解除?)されたというのは、コネクションの接続のこととは、また違う部分の話なのではないのかな。と推測しています。

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

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

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

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

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

投稿2017/01/31 09:30

PineMatsu

総合スコア3579

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

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などで英語で検索すると、たくさん参考になりそうなものが出てきます。

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

投稿2017/01/31 09:08

BEACHSIDE

総合スコア294

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問