2

私は次のかなり奇妙な動作をしています:

フェッチャーは、データベースからかなり多数のクエリを実行し、PreparedStatementクエリ間でデータベース接続を開いたままにする を使用します。アプリケーション全体は、メイン メソッドから起動するか、Tomcat にデプロイしてから Web アプリ経由でトリガーできます (実行されるコードはどちらの場合も同じままです)。

main-mamethod によるローカル実行では期待どおりのデータが得られますが、tomcat による実行ではそうではありません。エラーを次のように突き止めました。

/* Statement is a PreparedStatement which is initialized at 
 * the start of the execution and reused until the execution
 * is completed */
ResultSet rs = stmt.executeQuery(); 
/* Commenting out this line gives me correct data in tomcat
 * and main method, leaving it in corrupts data only in tomcat */
rs.setFetchSize(2000);
while (rs.next) {
  doStuff(rs);
}
rs.close();

なぜ私がここで困惑したのか理解できるかもしれません。ResultSet.setFetchSize()使用後に結果セットが閉じられている場合でも、コードの正確性に影響を与えるのはなぜですか? また、Tomcat で実行した場合にのみ破損するのはなぜですか?

編集

データベースから選択された列がデータベース内のデータと一致しません。つまり、データベースには、識別子とその識別子の有効期限の 2 つのキー列があります。1 つの行からフェッチされたデータ列を sqldeveloper によって提供されたデータと一致させると、それらは一致しません。

例: SQL 開発者は、次の行を期待するように指示します。

 ID   |  VALIDITY  | HOUR_1 | HOUR_2 |...
------+------------+--------+--------+...
 1897 | 01.01.2013 | 100000 | 100000 |...

それでも私は取り戻す

 ID   |  VALIDITY  | HOUR_1 | HOUR_2 |...
------+------------+--------+--------+...
 1897 | 01.01.2013 |  14000 |  14000 |...

興味深いことに、一部の列は正しくフェッチされています。1 つの例では 365 行が取得され、最初の 10 行は正しく (10 は Oracle のデフォルトの fetchSize - 偶然ですか?)、次の 355 行は間違っています。

OracleResultSetまた、フェッチサイズの設定が実際の結果サイズよりも大きい場合、SQLExceptionがスローされることがjavadocに示されているため、フェッチサイズをまったく設定することは最良のアイデアではない可能性があるというヒントも見つかりました。ただし、静かに間違ったデータだけで例外は発生しません。

4

1 に答える 1

2

基本的に、私の問題は、classpath-library-clash とドライバーのバグの 2 つの部分で構成されています。

私は、Oracle11 ドライバーの隣に springsource-oracle10 ドライバーが maven の依存関係に忍び込んでいることに気付きました。アプリケーションをローカルで実行する場合、webapp-project のみが oracle10-spring ドライバーに依存していましたが、サーバーには何らかの理由で Oracle10 が常に Oracle 11 よりも選択されていたため、これは問題ではありませんでした。

次に、少なくとも Oracle 11 DB に接続するときに、Oracle 10 ドライバーにバグがあります。OracleResultSet の javadoc で宣言された SQLException の代わりにフェッチ サイズを大きく設定しすぎると、さらに厄介なことが起こります。

例を挙げて説明します。同じクエリを複数回実行すると仮定すると、最初の実行で 30 行、2 回目の実行で 60 行、3 回目の実行で 30 行が得られます。fetch-size を 50 に設定します。

これで、最初の実行で正しい (期待される) 結果が得られ、2 回目の実行でも結果が得られます。しかし、3 回目のクエリ実行では 10 行 (Oracle standard-fetch-size) しか正しい行が得られず、残りの 20 行は 2 回目の実行から得られますが、ここでは複雑になりますが、ステートメントのすべてのパラメーター列は次のように設定されます。ステートメントで設定されたパラメーター値。

于 2013-04-03T18:44:51.673 に答える