Updated 1997/08/03
By 富士通SSL)福岡寿和
RDO2.0の新機能―スタンドアロン オブジェクト―
RDO2.0の新機能―バッチカーソル―
RDO2.0の新機能―バッチ更新―
RDO2.0の新機能―イベントドリブン―
RDO2.0の新機能―ユーザーコネクションデザイナ―
RDO2.0の活用−RDO2.0をOracleで使ってみる−
みなさんは、RDOを使っていますか?
RDOは、ODBCドライバさえ揃えばデータベースに依存しないプログラムインターフェイスを提供します(図1)。
ですから、もっと普及していてもいいはずですが、思ったほど開発で使われていないようです。これは、RDOがRDBMSに対応したODBCドライバの機能や性能に影響を受けることが原因かもしれません。
Visual Basic 5.0になって、RDO(Remote Data Object)は1.0から2.0に変わりました。今回のバージョンアップでは、全体的な動作をDAO(Data Access Object)に合わせる方向に修正した以外に、様々な新機能も追加されています。
しかし、RDOがODBCを使うことに変更はありません。 なお、RDOは、Visual Basic 5.0のEnterprise版以上で使えます。
図2 RDO2.0のオブジェクト構造図
Set rdcnnODBC = New rdoConnection
そして、プロパティの値を設定したらEstablishConnectionメソッドを使ってデータベースと実際に接続します。
rdcnnODBC.EstablishConnection
スタンドアロンrdoConnectionオブジェクトを宣言したとき、または EstablishConnectionメソッドを使用したときは、スタンドアロンrdoConnectionオブジェクトがrdoConnectionsコレクションに自動的に追加されません。スタンドアロンrdoConnectionオブジェクトを rdoConnectionsコレクションに追加するにはrdoConnections.Addメソッドを、rdoConnectionsコレクションから削除するにはrdoConnections.Removeメソッドをそれぞれ使用します。
☆RDOの復習―ODBCカーソル―
ODBCカーソルは、データベースの検索結果や現在処理しているレコードの情報をクライアント側のメモリ(および仮想メモリ領域のディスク上)に格納します。このため、データベースの検索結果を得るときに、サーバーからクライアントに多くのデータが流れます。この仕様は、検索結果のレコード数が少ないときはまだ良いのですが、検索結果のレコード数が増加すると、急激に処理速度が低下します。テスト環境と実環境でデータベースのデータ件数の違いから検索結果のレコード数が異なるときは注意が必要です。
しかし、ODBCカーソルは、データベースの構成などの影響を受けない特徴があります。そのため、データベースサーバーが実運用中であったり、管理が他社であったりするためにデータベースの構成を変更できないときに有効なカーソルです。
☆RDOの復習―サーバーカーソルー
サーバーカーソルは、データベースの検索結果や現在処理しているレコードの情報をサーバーのtempdbに格納します。このため、ネットワークやクライアントの資源を使わないので、従来のODBCカーソルよりも大幅に性能が向上します。ただし、ユーザー数が多く、カーソルが大きすぎてサーバーの資源を使い切ってしまうようなときには適しません。
また、サーバーカーソルをサポートしていないデータベースもあるので、開発に入る前に動作確認をした方が良いでしょう。
● バッチカーソル
RDO2.0の新機能であるバッチカーソルは、一度に大量のレコードを読込んできてそのほとんどを変更するようなときに効果的です。バッチカーソルは、レコードに対する処理全体が終了してから実際にデータベースへデータを反映するので、サーバーやネットワークへの影響を最小に押さえることができて、他のカーソルよりも良好な性能を示します。
ODBCカーソル、サーバーカーソル、バッチカーソルのカーソル移動性能をサンプルプログラム(リスト1、図3)で測定した結果は、図4のようになります。このグラフで、途中からODBCカーソルの性能が極端に悪くなっていることが判ります。これは、ある件数以上の結果セットに対してカーソルを移動したときに、ディスクスワップが発生するためです。
図5 サーバーカーソルサンプルでの同時更新の結果
図6 ODBCカーソルサンプルでの同時更新の結果
図7 同時更新の問題
これが同時更新の問題です。バッチカーソルを使ってバッチオプティミスティック更新(以下、バッチ更新とします)すれば、この問題を回避することができます。
| rdKey (規定値) | WHERE句に入っているキー列のみを使って、データベース上の行を識別し、データが変更されていないかを判断します。 |
| rdKeyAndUpdatable | WHERE句に入っているキー列および更新されたすべての列を使って、データベース上の行を識別し、データが変更されていないかを判断します。 |
| dKeyAndModified | WHERE句に入っているキー列およびすべての列を使って、データベース上の行を識別し、データが変更されていないかを判断します。 |
| rdKeyAndTimestamp | TIMESTAMP列があるときにのみに有効。ローカルな結果セットのTIMESTAMP列とデータベース上の列を比較することで、データが変更されていないかを判断します。 |
そして、行単位の更新可否はBatchCollisionRowsプロパティに設定され、BatchCollisionCountプロパティに更新実行中に発生した衝突の行数が設定されます(リスト2、図8)。このため、ページ排他のSQL Serverが図らずもレコード排他のRDBMSのように動作します。
また、バッチ更新はRDC(リモートデータコントロール)でも使えるので、RDCとバインドしたDbGridの更新をカレント行の移動ではなくプログラムで制御できます。そのため、カレント行が移動したときよりも、一覧表示されている内容をすべて確認したときにデータベースの値が変わるような仕様の実現にもバッチ更新は効果的です。
☆RDOの復習―非同期実行−
ConnectメソッドやOpenResultsetメソッドを実行するときに非同期オプションを使うと、制御がすぐにアプリケーションに戻ってきます。そして、アプリケーションは、StillConnectプロパティやStillExecuteプロパティの値を定期的に確認しながら、他の処理を実行できます、また、ボタンのクリックなどの他のイベントも発生しますので、利用者が時間がかかりすぎると思ったら、処理を中止することもできます(リスト3)。
● イベントドリブン
Visual Basic 5.0とRDO2.0を使うとrdoEngineオブジェクト、rdoConnectionオブジェクトおよびrdoResultsetオブジェクトにイベントを付加できます(表2)。
| オブジェクト | イベント | |
|---|---|---|
| rdoEngine | InfoMessage | ODBCドライバからエラー情報が返却された。 |
| rdoConnection | BeforeConect | サーバーと接続を確立しようとしている |
| Connect | サーバーと接続が確立した | |
| Disconnect | サーバーとの接続を閉じた | |
| QueryTimeout | SQLの実行時間がQueryTimeを超えた | |
| QueryCompleted | SQLの結果として1件目が取得できた | |
| WillExecute | SQLを実行しようとしている | rdoResultset | Associate | 結果セットが新しいrdoConnectionに関連付けられた |
| Disociate | 結果セットがrdoConnectionから切り離された | |
| ResultsChanged | 新しい結果セットが使えるようになった | |
| RowCurnncyChange | カレント行が移動した | |
| RowStatusChange | カレント行のデータの状態が変化しました | |
| WillAssociate | 結果セットを新しいrdoConnectionに関連付けようとしている | |
| WillDissociate | rdoConnectionから接続が切り離されようとしている | |
| WillUpDateRows | データベースへの更新が発生しようとしている | |
そして、イベントを付加すれば、メソッドの終了を調べるのにStillConnectプロパティやStillExecuteプロパティの値を定期的に確認する必要がありません(リスト4、図9)
図10 ユーザーコネクションデザイナ
図11 Queryオブジェクトのプロパティウィンドウ
図12 UserConnectionオブジェクトのプロパティウィンドウ
図13 Oracleに対するバッチ更新の実行
このことから、RDO2.0と共に提供されるOracle用ODBCドライバを使ってもすべての機能が正常動作しないことが判りました。しかも、レコード移動の性能測定の結果も余り良くありません(図14・15)。ODBCの出来がRDOの機能や性能に大きく影響していることが判ります。
図14 RDO2.0/Oracleベンチマーク
図15 カーソル別/レコード件数別移動時間グラフ
また、今回のサンプルでは、ほとんどプログラムソースを変更せずに動作しましたが、これは単純なSQL文で確認したからです。ODBCが統一するのは、あくまでプログラムインターフェイスであることに注意してください。
そのインターフェイス上を流れるSQL文までが各RDBMSに依存しない訳ではありません。そして、SQL ServerとOracle7が同じSQLで動作するのは、今回のような基本的な部分であり、ストアドプロシージャなどはまったく別物です。ですから、RDOを使ってSQL ServerとOracle7の両方で稼動する業務アプリケーションを設計するときは、各RDBMSの性能を充分引き出せないことを覚悟しておく必要があります。
結局は、RDBMSを使うときは、そのRDBMSの癖や機能のノウハウを持っているか否かがプロジェクト成功のキーポイントになります。
Visual Basic
開発者の手引き | Visual
Basicコースホームページ
int21 ホームページ | PCDN ホームページ