我有以下相当谨慎的行为:
一个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只是默默地错误的数据。
答案 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行将来自第二次执行但是 - 这里变得复杂 - 语句的所有参数列都将设置为语句中设置的参数值。