Visual Basic 中学校 掲示板 投稿の管理
タグのない投稿を抽出
統計
RSS
Visual Basic 中学校
投稿一覧
VB2010でADO.NET(SqlClient使用)での考え方
この投稿へのリンク
https://keijiban.umayadia.com/ThreadDetail.aspx?ThreadId=10908#CommentId23871
この投稿の削除
削除パスワード
削除する
コメント本文
投稿者
魔界の仮面弁士
 (社会人)
投稿日時
2012/6/14 20:57:05
> 1.プログラム起動時にDBへ接続(ADOです。)
> 2.各プログラムの処理では、Connectionは、使い回しで、RecordSetをオープンや、Excute
> 3.プログラムを終了する時に、接続解除
同時接続数が 1人 2人 ぐらいならば、繋ぎっぱなしで運用するケースもありますが、
そうした使い方は、データの一括取込・変換処理といったバッチ処理向けの方法ですね。
ユーザーが画面操作などを行うアプリの場合、データの取得・更新時間よりも
データを見ている/入力している時間の方が長いため、通信していないのに
コネクションが張られたままになります。
ゆえに ADODB であっても、adUseClient カーソルを通じて「切断型Recordset」が用いられたりします。
Open 後に AcitveConnection を切り離した Recordset の場合、MoveNext の速度も向上しますし、
更新頻度が少ない読み込み専用なテーブルなどでは、Recordset 自体を Save メソッドで
ローカルに保存しておき、次回以降は、それをキャッシュとして利用するといった使い方もできます。
また、そうした Recordset をオフラインで更新しておき、それをサーバーに反映させる段階で
ActiveConnection を再セットして、UpdateBatch メソッドで一括反映させるという使い方も可能です。
ただし幾度も Open/Close を繰り返してしまうと、再接続にかかる
タイムラグが生じるため、コネクションプーリングの併用は必要です。
……って、ADO の話はどうでも良いですね。本題は ADO.NET でした。
> 1.プログラム起動時にDBへ接続(SqlClient使用)
> 2.各処理で、SqlCommandやSqlDataReaderを使用
> 3.プログラムを終了する時に、接続解除
画面に表示して編集し、それをサーバーに登録するようなアプリでは、
データを DataTable に蓄え、それを DataAdapter/TableAdapter 経由で
反映させるといった使い方をします。
ユーザー操作を伴わず、無人でバッチ更新するようなケースでは、
SqlCommand だけでも良いでしょう。ただ、処理内容次第では、
VB 側で処理させるのではなく、SQL Server でストアド処理することも
検討してみてください。
> としたのですが、SqlDataReaderを開いている最中に、
SqlDataReader は、ADO でいうところの adUseServer + adOpenForwardOnly に近いモードであり、
いわゆる『ファイアホースカーソルモード』と呼ばれる状態を作り出します。
データ取得のために最高のパフォーマンスを誇る一方、データ取得のために
コネクションを占有しますので、他のコマンドを受け付けることができません。
VB6 においても、ファイアホースを開いている状態においては、他の処理が
・ファイアホースモードの間はトランザクションを開始できません。
・手動または分散トランザクション モードのため、新規接続を作成できません。
・データ プロバイダまたはほかのサービスが E_FAIL 状態を返しました。
・ITransaction::Commit または ITransaction::Abort が呼び出されました。オブジェクトはゾンビ状態です。
などのエラーを生じさせ、実行できなかったりします。
対応策としては、
(1) 別のコネクションを使って SQL を実行する。(トランザクション処理に注意)
(2) DataReader を使わず、DataAdapter + DataTable 経由で取得・更新するようにする。
(3) VB 側で処理しようとせず、ストアドを用いてサーバー側で処理させる。
などがありますが、個人的には 2 か 3 をお奨めしておきます。
第2案 のDataTable に格納するという行為は、ADODB でいうところの
adUseServer + adLockReadOnly に近い処理と言えます。
これはすなわち、SELECT した結果を全件ダウンロードする行為となりますので、
データ量が多い場合には向きません。その場合は第3案の利用を検討してみてください。
> DBアクセスごとに、DBの接続~解除をするのがセオリーなのでしょうか?
> みなさま、ご教授の程、宜しくお願い致します。
上記対応策のようにすれば、Connection 自体を Close せずとも処理できると思いますよ。
http://www.tt.rim.or.jp/~rudyard/torii009.html