ODBCでプログラミングをしたことがなくて、ODBCが遅いと勘違いしている人たちにお読みいただき記事です。一気に書くと長くなるので分割して掲載します。
2回目に入ります。
前回までの話で、「クエリーから結果セットを取ってくるまでのプロセス」は改善できました。なぜならSQLGetData()の呼び出しが列数分あったのがまったくなくなったのと、SQLExtendedFetch()を実行した段階で、結果セットが確保したメモリ空間に自動的にコピーされるようになったからです。
さて、ここからが厄介な課題です。顧客には結果のフェッチに関しての時間短縮が可能になったことを実際にデモンストレーションして、プロファイリングの結果も見ていただいて納得いただいています。しかし、次のような要求が提示されたのです。
・「追加・更新・削除」を高速化したい
・「行ロック」に対応してほしい
「ん?・・・」、自分の頭が真っ白になりました。心の中では「そんな無茶なぁー」と思いつつ、「調査の上、ご回答いたします」と言い切ってしまった自分がそこにいました。「そんなうまいこと、実装できるのか?」、矛盾を感じながら、Inside ODBCを読み進めていると、「おぉ、これが使えるかもしれない!」、見つけたのはSQLSetPos()という関数です。
ODBCドライバの実装にもよりますが、前後へのカーソル移動・行ロックが可能な処理系は存在します。これが可能なODBCドライバを利用すれば、SQLSetPos()というAPIが使えます。この関数、すごいことに、SQL文を一切書かなくても、現在のカーソルに対して、追加(※注1)・更新・削除・行ロックができてしまうものです。もちろんドライバとバックエンドデータベースがそれに追従できる実装がなされていなければどうにもならないのですが・・・。
そこからは、必死でした。実装の可能性はあるけれども、実行可能性については誰も証明していない、私自身がやるしかなかったからです。まずは、Visual C++で確認を取りました。そして結果は・・・。「信じられない。本当に実行できるんだ!」
何度も自分の目を疑いました。何度もデータベースの中を確認して、期待通りの動きをすることがわかり、ガッツポーズ(笑)。
顧客へ報告し、実際にデモンストレーションしました。追加のデモは、楽な部類でした。それ以外はクリティカルな処理なので失敗は許されません。特に行ロックは2台のマシンを使い、数人の人に囲まれながら、あるマシンが特定行をロックしていると、別のマシンがその行をロックできなくて待たされる、という現象を実際に体験してもらい、実証しました。あの時の緊張は忘れません。だって、「できる」といってできなかったら信用問題ですからね。
実行可能性は確認でき、顧客にも納得していただけました。
最後の課題は、既存のコードを書き換えないで高速化するというものです。
これをどう解決したかは、第3回に。
※注1: ODBC 3.xに詳しい人は、SQLSetPos()のSQL_ADD操作が廃止の方向になり、代わりにSQLBulkOperations()を使うということをご存知かと思います。
?