- - PR -
異なるバージョンのJDBCドライバの同時使用
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2004-12-20 17:11
こんにちは、カーニーです。
JavaからOracleデータベースにアクセスするためのJDBCドライバには、いくつかのバージョンがあります。そしてドライバのバージョンによって接続可能なOracleデータベースのバージョンも変わります。以下はその一例です。
さて、Tomcat上で動作するWebアプリケーションから、Oracle7.3とOracle9.2の両方に同時にアクセスする必要があります。 7.3と9.2の両方への接続をサポートするJDBCドライバは存在しないので、2つのバージョンのJDBCドライバを使い分けてやらないといけません。しかしドライバクラスの名前は両者で同じです。 さて、どうしたもんか、ということで皆様のお力をお借りしたく思ってます。 ■アイディアその1 2つのURLClassLoaderオブジェクトを使って、2つのバージョンのドライバを同時使用できないかと考えました。しかしDB接続時、 DriverManager.getConnection(url, username, password) するときに、そのリクエストをどっちのドライバに処理させるかを指定する方法が見当たらない。 ■アイディアその2 9.2への接続と、7.3への接続を、別個のWebアプリケーションで行う。 ドライバクラスは各Webアプリの WEB-INF/lib に配置して、異なるクラスローダでロードされるようにする。 必要に応じて2つのWebアプリ間で通信を行う。 以上のアイディアについて、
などなど、色々なご意見を伺いたく、よろしくお願いします。 | ||||
|
投稿日時: 2004-12-20 17:47
よんどころない事情がおありかもしれませんが、Oracle 7.3 に入っているデータを Oracle 9.2 に移行してしまうという選択肢はいかがでしょうか。
もし可能であれば、これが一番簡単な方法と思います。 以下、この方法がダメな場合について考えてみます。 まずアイデア1は確かに方法がありません。 クラスローダは木構造を成し、要求した完全限定名のクラスがルート(システムデフォルト)のクラスローダで見つからない場合、子のクラスローダに委譲します。 一旦見つかるとそれで探索を終了するので、どちらか一方のドライバは完全に隠れてしまいます。 スレッド単位で分けてもこの制約からは逃れられないので、更に大きな単位、つまりプロセスで分割するアイデア2は現実性があると思いました。 けれども高トランザクションで両方のデータベースを更新するケースがあったりすると、二つの AP サーバ間での連携という新たなボトルネックが発生するおそれはあります。 以上、ほとんど参考にならないかもしれませんが、私見を述べてみました。 | ||||
|
投稿日時: 2004-12-20 18:28
クラスの衝突を避けるという意味では別の Webアプリケーションにするのが良いでしょう。
しかし同じ Tomcat 内で通信ってどのような形をかんがえているでしょうか? 双方にリクエストを出すような仕組みだったらデッドロックを引き起こす可能性がありますので気をつけましょう。 例えばスレッド数が最大数の時にお互いの Web アプリケーションを呼び出すようなリクエストをしたらいつまでたっても処理は行われません。 DriverManager.getConnection() もデッドロックを引き起こす可能性がありますので避けましょう。 http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=10107&forum=12&start=8&10 古いデータベースに入っているデータは即時性を求められないことが多いのでバッチ処理で定期的に 9.2 の DB にコピーするというのはいかがでしょうか。 | ||||
|
投稿日時: 2004-12-20 19:14
データベースリンクって方法もありますが、
提示されている環境ですと、標準では対応していないみたいですね。 http://www.oracle.co.jp/products/system/matrix_db.html 種類問わずデータベース間でリンクを張ることができるツールもあるみたいですが、 パフォーマンスがいまいちみたいです。 Windowsならデータソースの設定を行い ODBC-JDBCブリッジドライバで接続するっていう方法もありますね。 まったく別のドライバならDriverManagerで別々のコネクションを取得できます。 色々書いてみたのですが、結局方法論でしかなく、 Gioさんやインギさんが仰るように DBの移行・コピーという方法が一番いいと思います。 | ||||
|
投稿日時: 2004-12-20 19:29
Gioさん、インギさん、かつのりさん、
貴重なご意見をどうもありがとうございます。 私が作ろうとしているアプリケーションは業務向けではなく、汎用DB管理ツール、のようなものだとお考え下さい。 業務的には全く関連のない複数のDBを、Tomcatアプリから統合管理するので、ターゲットDBのバージョンアップも、バッチによるデータコピーも残念ながらNGです。 ご意見伺う限り、どうやら「複数Webアプリ」が良さそうですね。こんな感じの構成で。 1)Oracle9.2監視アプリ(画面無しのバックグラウンドプロセス) 2)Oracle7.3監視アプリ(同上) 3)統合コンソールアプリ 1 -> 3、2 -> 3 の片方向通信になるよう考慮すれば、やっかいな問題も避けられそうです。 肝心の通信方法はHTTPでもいいんですが、ローカルRDBがあるので、そこを介する方法も考えられそうです。 いずれにしても非常に参考になる意見を聞くことができて、大変助かりました。 どうもありがとうございました。 [ メッセージ編集済み 編集者: カーニー 編集日時 2004-12-20 19:49 ] | ||||
|
投稿日時: 2004-12-27 15:56
いまさら書き込みするのもなんですが・・・・
Oracle 9.0.1だったらOracle 7とのDBリンクがサポートされていたような気がします。 (ヴァージョンアップは不可とはありましたが参考までに) あと、Oracle 9.2とOracle 7.3を共にDBリンク張れて、参照が可能な Oracle 8または、Oracle 9.0.1のDBを一つ用意して そこに参照したいテーブルを用意し WEBアプリケーションから接続を一括するのはいかがでしょうか? この場合、JDBCが一つになるかと思います。 構成はこんな感じかな 1)監視用DBサーバ(oracle8〜9.0.1) 2)監視アプリ 3)DB(oracle7) 4)DB(oracle9.2) 2→1 1→3 1→4 | ||||
|
投稿日時: 2004-12-27 17:58
私もいまさらって感じで書き込みしますが、
各JDBCドライバ用にクラスローダを分けてクラスのロードを行えば、 クラスの衝突が起こらないような気がします。。。 デフォルトのクラスローダを親クラスローダとして持つクラスローダを、 ドライバ名+バージョンをキーにマップに格納すると言う方法で可能なような気がします。 間違ってたら詳しい方、突っ込みいれてください。 ![]() | ||||
|
投稿日時: 2004-12-28 00:43
JDBCドライバだけでなく、DriverManagerも両方でロードすれば、僕が最初に書いた問題も解決ってことですかね? |