setch-queries的奇怪行为,其获取大小设置为高量

时间:2013-04-03 10:07:22

标签: oracle tomcat jdbc

我有以下相当谨慎的行为:

一个fetcher从数据库执行相当多的查询,并使用PreparedStatement来保持数据库连接在查询之间保持打开状态。整个应用程序既可以从main方法启动,也可以在tomcat中部署,然后通过Web应用程序触发(在两种情况下执行的代码保持不变)。

虽然通过main-maethod的本地执行产生了我期望的数据,但是通过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中执行时才会出现损坏?

修改

从数据库中选择的列与数据库中的数据不匹配,即在数据库中有两个键列,一个鉴别符和该鉴别符的有效日期。如果我将来自一行的读取数据列与sqldeveloper给出的数据匹配,则它们不匹配。

实施例: SQL-Developer告诉我期望以下行:

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

然而我检索

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

有趣的是,一些列被正确获取,在一个示例中检索了365行,前10个是正确的(10个是Oracle中的默认fetchSize - 巧合?)而后面的355是错误的。

我还发现了一些提示,meybe在OracleResultSet中设置fetchsize可能不是最好的主意,因为javadoc告诉我如果fetchsize设置大于实际值,则抛出SQLException resultsize。但是,我没有得到一个Exception只是默默地错误的数据。

1 个答案:

答案 0 :(得分:2)

基本上,我的问题包括两个部分,一个是classpath-library-clash和一个驱动程序错误。

我刚刚意识到,在Oracle11驱动程序旁边,一个springsource-oracle10驱动程序潜入了maven依赖项。在本地执行应用程序时,这没有问题,因为只有webapp-project依赖于oracle10-spring驱动程序,但出于某种原因在服务器上,Oracle10始终是通过Oracle 11选择的。

接下来,Oracle 10驱动程序中存在一个错误,至少在连接到Oracle 11 DB时:如果将获取大小设置得过高而不是在OracleResultSet的javadoc中声明的SQLException,则会发生更多的偷偷摸摸的事情。

我将举例说明。假设您有多个相同查询的执行,第一次执行将给你30行,第二次执行将给你60行,第三次执行30行。您将fetch-size设置为50。

现在,第一次执行将为您提供正确的(预期)结果,第二次执行也是如此。但是第三次​​查询执行只会给你10个正确的行(Oracle标准提取大小),剩下的20行将来自第二次执行但是 - 这里变得复杂 - 语句的所有参数列都将设置为语句中设置的参数值。