ConnectionString を使ったり使わなかったり

データセットデザイナは、作業中、頻繁に DB サーバとやり取りをします。
これは、その DB サーバに登録されている Table やView 等の情報を取得してるんですね。

ので、テーブル設計書とか参照しながらコツコツと文字列で SQL 文を組む必要がなく、型や桁の設定ミスも防げ、簡単に高品質なアクセスロジックを組めるというスゴいメリットを持っているわけです。

が、当然これはあらかじめ DB サーバにそれなりの状況をあらかじめ構築しておくことが前提となっておりまして。
かつ、デザイナに DB サーバへアクセスできる設定を入れてやらなければならない、ということでもあります。

具体的には、デザイナを新規作成して右クリック → [追加] → [TableAdapter] で新規テーブルアダプタを作成するような場合、構成ウィザードの第一画面が

みたいな感じになります。
これは、「これからテーブルアダプタを作るにあたって、どの DB サーバから情報持ってくればいいっすか?」とウィザードが訊いてきているわけですね。
ここで指定した情報を 接続文字列 として保存し、後続の作業を始めていくわけですが。

気になるのはその次の画面で、

接続文字列をアプリケーション構成ファイルに保存しますか?

と訊いてくるんですが、保存したら/しなかったら、どんないいこと/悪いことがあるのかよくわかりません。

ということで、このへんをちょっと調べてみたいと思います。


検証環境 自作マシン(Core2QuadQ9400 2.66GHz/4GB)
Windows7 Ultimate(6.1.7600) – x86
VisualStudio2008Pro(VB) 9.0.30729.1SP/.NET Framework 3.5SP1
Oracle Database 11g 11.1.0.6.0
Oracle Developer Tools for Visual Studio 11.1.0.7.20

まず、接続文字列をアプリケーション構成ファイルに保存「した」場合。

実際には、接続文字列はプロジェクトプロパティの[設定]タブに登録されます。

ファイル的には、プロジェクトフォルダの app.config の <configuration>-<connectionStrings> タブと、プロジェクト\My Project フォルダの Settings.settings の <SettingsFile>-<Settings>-<Setting>-<DesignTimeValue> タブの 2 か所に保存されます。

次、接続文字列をアプリケーション構成ファイルに保存「しない」場合。

こちらは、特に IDE上では確認できません。TableAdapter 構成ウィザードを再度起動させれば、設定状態はわかりますが。

ファイル的には、そのデータセットの .xsd ファイルの <xs:schema>-<xs:annotation>-<xs:appinfo>-<DataSource>-<Connections>-<Connection> タブに保存されます。
<Connection> タブには Name 属性に名称が設定されており、各テーブルアダプタ側の情報には<xs:schema>-<xs:annotation>-<xs:appinfo>-<DataSource>-<Tables>-<TableAdapter>-<MainSource>-<DbSource> タブの ConnectionRef 属性に使用する <Connection> タブの名称が指定されているというカラクリですね。

まあ、そんだけの話なんですけれども。
保存されるファイルと位置が異なるだけで、情報量としては変わるわけではありませんし。


と思っておったわけですよ。
実際に本業のプロジェクトで採用してみるまでは。

たとえば、製造チームと検証チームが分かれていたとしましょう。
製造チームが 3 チーム、各チームの DB サーバが SEIZO.SEIZO1 ~ SEIZO.SEIZO3、検証チームが KENSHO.KENSHO でそれぞれ作業しているという前提で。

本番運用ではまた別の、お客様の DB サーバに接続しますので、データセットデザイナでどこの DB に接続していてもかまわないように、別途用意した接続文字列で生成した Connection インスタンスをデータセットに割り当てて使用するという規約にして OKOK だと思っていたんですが。

UsingoConn = New Oracle.DataAccess.Client.OracleConnection
    oConn.ConnectionString = "(別途用意したシステム共通の接続文字列)"
    oConn.Open()
    Using ta = New DataSet1TableAdapters.TBL_PARENTTableAdapter
        ta.Connection = oConn
        Using ds = ta.GetData()
            '……

まあこんな感じで。

そしたら。

実際に実行させてブラックボックステストする分には差し支えなかったんですが。
いざ障害が発生して、どんな SQL 吐いているのかとデザイナウィンドウを開いて TableAdapter構成ウィザードを起動させると、

もういちいちフリーズかとみまがうほどに反応が遅く。

どうも存在しない接続文字列が埋め込まれていると、どっかに設定されているらしいタイムアウトまで延々とネットワーク内を探しに行っているようなんですね。

これはたまらん、とりあえず検証側に回ってきたソースの接続文字列を KENSHO.KENSHO に差し替えようとしたんですが。
ConnectionString で外出しされている場合はまずそこを書き換えればよかったんですが、直接 .xsd ファイルに埋め込まれている場合は、まず 構成ウィザードを起動しなければ変更できないため、膨大な待ち時間が発生してしまったのでした。

中でも、ひとつのデザイナウィンドウで複数のテーブルアダプタを保持していると、ひとつ修正してウィザードを閉じるたびに、他の(まだ修正していない)テーブルアダプタまで再検証に行くらしく。

つことでたとえば 10 個のテーブルアダプタが保持されているデザイナ画面で最初の 1 つめのテーブルアダプタを修正すると、

((起動時に 1 テーブルアダプタ分)+(完了時に 10 テーブルアダプタ分))×タイムアウト時間

と 11 タイムアウト時間分だけ待ち時間が発生するわけです。

2 つめのテーブルアダプタを修正する場合には、1 つめのテーブルアダプタはすでに修正が完了しているのでその分待ち時間は少なくなります。
修正完了したテーブルアダプタの再検証が 0 秒で終わると仮定すると、

((起動時に 1 テーブルアダプタ分)+(完了時に 9 テーブルアダプタ分))×タイムアウト時間

で 10 タイムアウト時間分の待ち時間。

という仮定で行くと、10 個のテーブルアダプタを修正する総待ち時間は

11+10+9+8+7+6+5+4+3+2=65 タイムアウト時間。

1 タイムアウト時間を 1 分とすると、実に 1 時間以上のロスタイムが。これはきつい。

実際の作業では待ち時間にブレがありましたし、上記の原因も計算式もあくまでも動作から推測した大雑把な仮定ですので、実際にはもっと違う内部動作を行っているのかもしれません。あるいはネットワークや DBサーバの構成も待ち時間のパラメータになっているのかもしれません。

が、後の方になるほど構成ウィザードの起動 → 完了にかかる時間が短くなったのは確かですし、待ち時間もこんな感じでしたので、おばあちゃんの知恵袋的な経験則としてはあながちそんなに的はずれではないのではないかと思っています。


ということで、完成したプログラムの動作とは別に。

複数人で分散した環境でデータセットデザイナを使ったシステムを構築するのであれば、アプリケーション設定ファイルへの接続文字列外出しは

必須。

だと痛感しましたよ。


このエントリを書くにあたって、自宅の環境で上記の現象を何パターンか再現してみたんですが、単純なネットワーク・DB・テーブル構成では、それでも比較的スムースに ConnectionString への外出し作業が行えました。

が、本業のプロジェクトの作業環境はネットワークにぶら下がっているクライアント数、DB サーバ数、DB サーバあたりのスキーマ数、スキーマあたりのオブジェクト数、オブジェクトあたりの項目数が桁違いでして。
待ち時間も桁違い、処理しきれなくて IDE ごと途中でフリーズかかること多々あり、という中での修正作業となってしまいました。

つらかったすー。

コメントを投稿