ADO.NETでの注意

2010.03.10 Wednesday 09:37
0

    昨年春ごろから、SQL Server を使ってサーバーアプリを構築しています。
    普段はクライアントサーバー方式で、サーバーはオラクルデータベースのみを設置するような方式をとるのですが、
    この案件では SQL Server を使用し、サーバー側で処理をするプログラムとなるので、全然方式が違います。

    まずは、サーバーのプログラムはサービスにする必要があります。
    サービスとは、Windowsが起動すると同時に動作するように設定されたプログラムですが、メニューにあるスタートアップ
    などと違い、デスクトップを表示しなくても動作する内部プログラムです。

    もしサーバーが再起動したときでも画面にログオンしなくても動作するので便利です。
    というより、サービスにしないとそもそも使い物になりません。

    そしてクライアントや外部からのイベントをもとにデータベースにアクセスし、追加や検索を行ってクライアントに返します。

    この場合、処理にスレッドは使用しません。
    スレッドを使用するとよいように思えますが、クライアントからのアクセス数が確定できないものなので、いくらでもスレッドで
    要求を受け付けるのは大変危険です。
    ですので通常のイベントドリブンでマルチ的に動作する仕組みになります。

    そうすると気になるのがデータベースへの排他制御です。
    同時に同じレコードへのアクセスが発生した場合は、それが原因でデータベースの不整合が発生する可能性があります。

    不整合の発生する原因としては
     1.レコード番号などのユニークキーが重複する
     2.同一レコードの更新処理がかぶる
    ということがありますが、回避方法があります。

    1は、SQL Serverであれば、IDENTITY というプロパティがありますので、これを使用してINSERTしたときにOUTPUTで追加した番号を取得する方法があります。
    もしこれはオラクルであれば、SEQUENCEを使う方法とか、SELECT - FOR UPDATE などを使ってレコード情報を管理することで回避が可能です。
    こういうオプションはSQL Serverにはなく、やはりオラクルは便利だと思いました。

    2は、処理的に同じレコードのデッドロックがかかる処理が発生しないような設計にします。
    特にサーバープログラムでは、そのプログラム1つだけでデッドロックがかかるので非常に厄介なので、絶対に発生しないような構造が必要です。

    と、このように処理を作成していたのですが、どうも動きがあやしいところが出てきました。
    そうして色々と解析しているうちに、ある重大なことに気がつきました。

    SELECTの記述に、ADO.NETのDataReaderを使用していたのです!!

    DataReaderは、1つのコネクトに対して1つしか使用できないという制約があります。
    ふつうのクライアントアプリでは問題ないのですが、マルチで動作するサーバー側アプリなどでは、他の処理でDataReaderで処理をしている最中に、別のdataReaderは動作できません。 (いったんクローズしないといけないのです!)

    理由は簡単で、DataReaderは現在よみとっているレコードのポインタとそのレコード1行のデータのみメモリに読み込む方式だからです。
    そのため、メモリを占有しないので大容量のデータを処理するときに用いられます。

    ということで、DataReader記述をすべて DataAdapter/DataSet 記述に変更しました。
    よく考えてみればこの処理では、データ結果がほぼ1件しかかえって来ない検索でしたので、この方式で全く問題がなかったのです。

    サーバーアプリですと、デバッグログもなかなかチェックしにくいので、私はデバッグログ自体もデータベースに出力するようにしています。
    こういうときにも、DataReaderを使用していると、オープンからクローズの間は別処理が行えませんので、ログも吐き出すことができなくなりますので、できる限り DataAdapter/DataSetに変更するのが望ましいといえますね。


    category:プログラミング | by:comments(0) | -

    PHPでの開発とブラウザの種類

    2009.07.24 Friday 04:04
    0
      PHP開発で「しまった!」ということがあった。

      客先でデモをしたときのことでしたが、客先は XP で ブラウザは IE6 を使っています。
      そうしたら、スタイルシートでの表示部分がずれて表示されています!!

      「ありゃーーー!! デザインが台無しやん!?」

      実は私の開発環境はIE8、及び Google Chromeです。

      おそらくバージョンの違いということで、帰社してから調べてみると、IE6以前では正常に
      表示されない設定のようでした。。

      こう考えると、頻繁にバージョンアップされるブラウザ競争の度に、その検証環境を作っていかないといけないのはとても大変ですね。。

      せめてIEだけでも表示は統一してほしいものです。 こちらはWindows Vista環境なので、IE6などはインストールできません。 かといってその為にXPを1台用意するのも・・と思っていたら、こんなソフトがありました。

      IE Tester (インストール時に Japanese を選択するとよいです)
      http://www.my-debugbar.com/wiki/IETester/HomePage

      このソフト1つで、IE5.5 と IE6、 IE7、 IE8 の表示テストが行えます!!

      ※このソフトでチェックしたら、やはりIE6以前では正常に表示されないCSSの記述があったようです。。
       しかし、、どうしたもんだか。。

      category:プログラミング | by:comments(0) | -

      アプリ(サービス)の依存関係

      2009.07.23 Thursday 09:24
      0
        弊社では CTI開発を行っています。普段は oracleデータベースを用いて開発を行うのですが、今回の依頼は Windows Server 2003で、SQL Server 2005 Express を用いた開発になります。

        CTIサーバーというのは、電話がかかってきたときに、その着信電話番号情報を顧客管理のデータベースを連結させて、その顧客の情報はもちろん、過去の取引や問合せ履歴などを瞬時に、各クライアントPC画面に表示させるというものです。

        既に開発は完了していて試験運用期間中なのですが、たまたまサーバーの電源が抜けました。。
        (試験用だったのでUPSに未接続・・)

        それに気がついて電源を入れなおしたのですが、CTIサーバーが正常に起動していません。。

        なぜだ・・ (>_<)


        イベントビューアーを見てみると原因が分かった。。
        SQL Server Express が修復プロセスに入っていて、起動に時間がかかっていたのです。
        その間にCTIサービスは起動しようとする為に、DB接続ができずにエラーとなりました。

        こういう電源が切れるという事象は ”通常運用ではない” にしろ、Windows Update 及び
        その他の理由で再起動はあり得る話であって、UPS ソフトが導入されていても、数分間の
        電源断があればシャットダウン(そして再起動)がかかります。
        それにデータが増えてくれば、DBの起動プロセスにも時間がかかるはず。。
        そう考えると、なんらかの対策をうたなければなりません。

        そこで、サービスの依存関係を設定します。

        これは、ServiceA と ServiceB というサービスがあったとします。
        この場合、ServiceA は ServiceBが起動していないと動作できない場合に、ServiceA側に、ServiceBを依存関係にセットすれば、ServiceB起動後にServiceAが起動します。

        設定方法は以下の通りで簡単。

        regedit.exeで以下を探す
         HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\(サービス名)
        「DependOnService」のキーを開き、「値のデータ」に先に起動したいサービス名を入力します。
        ※「DependOnService」のキーが存在していない場合はREG_MULTI_SZタイプで作成

        ここで注意なのは、「DependOnService」にセットするのはサービスの名称であって表示名ではないということです。 SQL Server EXPRESSの場合は "SQL Server (SQLEXPRESS)" ではなく、"MSSQL$SQLEXPRESS" となります。

        一度セットしたら、このレジストリの値をエクスポートし、サービスのインストール時に自動でセットするようにすればOKです。

        Windowsは、まだまだ奥が深いですね。

        category:プログラミング | by:comments(0) | -

        Calender
              1
        2345678
        9101112131415
        16171819202122
        23242526272829
        3031     
        << July 2017 >>
        弥生製品
        最高に安いレンタルサーバー
        ネット注文はアマゾン
        Selected entry
        Category
        Archives
        Recommend
        Link
        Profile
        Search
        Others
        Mobile
        qrcode
        Powered
        無料ブログ作成サービス JUGEM