Java 为什么将ResultSetType从类型\u SCROLL\u Responsible更改为类型\u FORWARD\u只会更改SQL查询的结果?

Java 为什么将ResultSetType从类型\u SCROLL\u Responsible更改为类型\u FORWARD\u只会更改SQL查询的结果?,java,jdbc,db2,db2-luw,isolation-level,Java,Jdbc,Db2,Db2 Luw,Isolation Level,在一个项目中,我们发现我们正在执行的一些SQL语句(但不是全部)在Java应用程序中返回的结果与在独立的SQL IDE(如Aquadata或Toad)中运行时不同。这使用一个DB2数据库 我无法显示实际数据(包含PHI),但我将模拟一个示例,让您了解发生了什么: AquaData结果(通过其他方式认为正确/有效): Java结果(通过其他方式认为不正确/无效): 因此,有几件事很突出: 其中一个计数(但不是全部)立即不正确(从34变为33) 其中一排完全没有 Count行的计算方法,顾名思义

在一个项目中,我们发现我们正在执行的一些SQL语句(但不是全部)在Java应用程序中返回的结果与在独立的SQL IDE(如Aquadata或Toad)中运行时不同。这使用一个DB2数据库

我无法显示实际数据(包含PHI),但我将模拟一个示例,让您了解发生了什么:

AquaData结果(通过其他方式认为正确/有效):

Java结果(通过其他方式认为不正确/无效):

因此,有几件事很突出:

  • 其中一个计数(但不是全部)立即不正确(从34变为33)
  • 其中一排完全没有
Count
行的计算方法,顾名思义,是根据
Count(*)
语句对SQL查询中的其他元素进行计数

然而,当我们深入研究代码时,我们发现,通过改变创建
PreparedStatement
对象的方式,可以使Java结果与其他结果完全匹配

旧版本(产生的结果不正确):

新版本(产生正确的结果):

这个简单的更改导致Java结果集与AquaData(和其他方法)结果集完全匹配。深入研究Java文档,唯一有意义的变化似乎是默认参数中的
TYPE\u SCROLL\u INSENSITIVE
参数改为
TYPE\u FORWARD\u only
;默认参数中的
CONCUR\u READ\u
参数未更改

为什么这会对我们的结果产生如此重大的影响?正如我们所知,此查询的基础数据在执行此代码之间(或执行期间)不会发生更改,因此更改滚动类型不会对结果集产生影响。那么,为什么我们会期望这种变化会对我们的结果产生如此重大的影响呢


其他信息:

DB2平台:Linux/Unix/Windows
DB2版本*:
10050700 3/22/2016 1:56:57 PM s151221
(DB2 LUW v10.5.0.7)

JDBC供应商:IBM
JDBC版本:3.69.24

Java供应商:IBM
Java版本:IBM 32位Windows SDK,Java技术版,版本7


*通过从sysibm.sysversions order by 2 desc执行
选择versionnumber、version\u timestamp、versionbuildlevel获取

键入\u滚动\u不敏感-…对结果集基础数据的更改不敏感。这意味着应用程序或服务器可以自由地预取数据,而不考虑在应用程序使用数据时数据是否会更改

键入\u FORWARD \u ONLY-…其光标只能向前移动的对象。但行在使用时会被检索

CONCUR_READ_ONLY-…您的ResultSet对象可能不会更新。这意味着锁可以立即释放

在不敏感的情况下,最终会出现一个“脏读”锁定机制,如果表同时被另一个应用程序更新,则可能会产生不同的结果集


我希望你的“错误”和“正确”案例总是在不断变化,并且不是每次都用完全相同的答案总是错误的

键入\u滚动\u不敏感-…对结果集基础数据的更改不敏感。这意味着应用程序或服务器可以自由地预取数据,而不考虑在应用程序使用数据时数据是否会更改

键入\u FORWARD \u ONLY-…其光标只能向前移动的对象。但行在使用时会被检索

CONCUR_READ_ONLY-…您的ResultSet对象可能不会更新。这意味着锁可以立即释放

在不敏感的情况下,最终会出现一个“脏读”锁定机制,如果表同时被另一个应用程序更新,则可能会产生不同的结果集


我希望你的“错误”和“正确”案例总是在不断变化,并且不是每次都用完全相同的答案总是错误的

我感谢你的回答,但不幸的是,错误和正确的案例总是错误和正确的。数据在执行之间没有变化,我能够在每种情况之间来回“切换”,以验证对已准备语句的更改是否导致行为的变化。这种差异可能是由于未提交的更改造成的。在sql中添加选项“with ur”,并在aquadata中运行它。如果问题是由于未限制的数据引起的,那么结果应该与Java结果集匹配(TYPE_SCROLL_INSENSITIVE)@Xirema您应该使用IBM支持人员打开一个案例。我感谢您尝试回答这个问题,但不幸的是,错误和正确的案例始终是错误和正确的。数据在执行之间没有变化,我能够在每种情况之间来回“切换”,以验证对已准备语句的更改是否导致行为的变化。这种差异可能是由于未提交的更改造成的。在sql中添加选项“with ur”,并在aquadata中运行它。如果问题是由于未限制的数据引起的,则结果应与Java结果集匹配(TYPE_SCROLL_INSENSITIVE)@Xirema您应使用IBM支持人员打开一个案例。如果基础数据未发生更改是正确的,则行为是有缺陷的。同样,如果任何数据(例如MQT或昵称对象或元数据中的数据)正在更改,则行为可能是正确的。您写道,一些查询(但不是全部)受到影响,因此使用它来缩小可能性。有时候,事情并不像它们看起来的那样,有时候你认为你是在一个一个地比较,但你不是。如果您缺乏所需的法医诊断技能,请向IBM Db2支持部门申请。这可能需要比熟练的现场问题确定更长的时间。如果可以证明基本数据是正确的
 Name         | ID            | Count
--------------|---------------|---------------
 Alexander    | 12345         | 15
 Debra        | 23456         | 34
 Igor         | 54321         | 3
 Francesca    | 34567         | 108
 Name         | ID            | Count
--------------|---------------|---------------
 Alexander    | 12345         | 15
 Debra        | 23456         | 33
 Igor         | 54321         | 3
try (PreparedStatement p = conn.prepareStatement(query,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)){
try (PreparedStatement p = conn.prepareStatement(query)) {