2017年2月7日火曜日

VB LocalDB とファイル操作 1-2

SQL Server の LocalDB を使ったアプリを書く上で、
その Database ファイルの操作 は 少し 留意が必要です。
データソースとなるファイルの履歴を別に保存し、 それを管理する時の事を考えましょうか。
DataGiridView や DataGrid で 一覧表示させながら、 ファイル操作もしたい ... 。


例えば、
一覧表示して見て、 あっ、このデータベースは古い! 確か、直した筈だ! なんて事があります。
  1台の機械( PC ) で作業が完結するなら、 こうした事は少ないのですが ... 。
  Client-Server で、サービスとして、DB エンジンを利用していれば、 こんな羽目にも合わないのですが ... 。
複数のローカル(その機械)上に、 データベースファイルを配置し、操作していると、
こんな状況に遭遇します。
ファイルを最新のものに替えないと ... 。


でも、
実は、大きな壁が立ち塞がります。


 それは、 LocalDB の仕組みと関係があります。


アプリを開いて気付いた データベース ファイル更新 の必要性 を達成するには、
普通、 そのアプリを閉じて操作しなければいけません。  後述。.
でも、 アプリを開いたまま、 操作を継続出来るに越した事はありませんね。
でも~ ... なのです。


Visual Studio で LocalDB を使った Project を作ると、 その Project は Database の接続文字列を持ちます。
LocalDB は、 Database から データを Fill しようがしまいが、 Project (アプリ)起動と共に、 データベースに接続し、
ユーザーの操作を待機します。

これが何を意味するのか?。

そう、 ファイルがロックされるのですね。
ですから、 ファイル操作しようと思っても、 出来ません!。
例外で落とされるか、 ロックが解除されるのを待ち続けるか、 に なる訳です。

そして、ややこしくしているのが、
一定時間が経過すると、 LocalDB は動作を停止し、
また、 必要になると 再起動 される と言う事です。
     必要になると とは データの読み書きが必要になった時 と言う事です。

言い換えれば、 LocalDB が停止( Process が終了している ) 時には ファイル操作が可能 となります。

でも、 その状態を Project (アプリ) に、直接、連絡してくれる訳ではありません。
簡単に言えば、 LocalDB 任せ!。
何時、 その状態が 停止 になるのかは 分からない ... と。




そこで、 Microsoft さま の Sysinternals の Process Explorer で 様子 を見て見ました。


Project の .exe の 子プロセス として、 LocalDB ( sqlservr.exe ) が動いているのが分かります。
動作環境に左右されるのかも知れませんが、 
無操作状態で 開始終了期間の目安 は 10 分前後 でした。  数値は?です。

       素晴らしい オチ もあります。
       ファイル操作したいのに、 何時まで経っても、 終わらない ... 。
       開発途中では、 Visual Studio の Server Explorer で Connection を 開けっぱなし だった とか ... 。
       これは、本筋からは外れるので 参考迄に です。.

   単純に考えれば、
   自分の起動した 子プロセス なのに、
   親である 自分 は、 子 の挙動に タッチ 出来ない そんな状況なのですね。

仮に、 この Process Explorer 上から、 LocalDB プロセス を Kill しても、
その後に、 ソフトから 編集保存や再読み込みを実施すれば、
また、新たに、 LocalDB が 起動 して、 正常に、 動作する様子が確認出来ます。



では、 闇雲に、 sqlservr.exe を Kill すれば良いのか? ... 。

待って下さい。

編集未保存状態のレコードが有ったり、 別のソフトで動いている LocalDB があれば、
それらも、 破棄や停止 してしまいます。
そうなれば、不都合が生じるかも知れない訳ですね。
未保存なら、アプリの書き方次第で対応出来ますが、 別のソフトは如何ともし難いですから。
やはり、
該当直下の sqlservr.exe のみ Kill しなければ いけません。



でも、 でも、 です。
上で書いて来た事は 基本 です。
他にも、パターンがあります。
それは、 起動した  sqlservr.exe は 別プロセス と言う 点 が着目すべき箇所です。

親が閉じられても、 子は生き続けます。

子に有効な残り時間があれば ですが。
そして、 その間に、 また、 新たに (別の) 親が 立ち上がると ... 。
前の子は、 別の親の 立ち上がらない子 の 替わり となり、 機能を果たします。

  整理して置きましょう。

    最初の親 Explorer.exe 直轄.
      最初の子 親 App1.exe  直下
    最初の親 閉じる
      最初の子 親だった PID を保持したまま、 親直下 から Explorer.exe 直轄外に 独立 (利用期限内なら).
    次の親  Explorer.exe 直轄.
      次の親の子 未出現
      最初の親の子 次の親をサポート

                ふた親は 共に 同じ プロセス名(App1.exe) だから 継続・引継ぎ可能なのか ?。.


あ~、 単純だけれど、 対応は 複雑怪奇 ... 。

一体、 どうすんだろ ... 。



と言う訳で、 コードを考えましょう。
ファイル操作の為の kill 対象の選別 ですね。
... 。
でも、 長くなったので、 続き は 次回にしたいと思います。



0 件のコメント:

コメントを投稿