java - 为什么将 ResultSetType 从 TYPE_SCROLL_INSENSITIVE 更改为 TYPE_FORWARD_ONLY 会更改 SQL 查询的结果?

标签 java jdbc db2 db2-luw isolation-level

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

我无法显示实际数据(包含 PHI),但我会模拟一个示例,让您了解正在发生的情况:

AquaData 结果(通过其他方式相信是正确/有效的):

 Name         | ID            | Count
--------------|---------------|---------------
 Alexander    | 12345         | 15
 Debra        | 23456         | 34
 Igor         | 54321         | 3
 Francesca    | 34567         | 108

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

 Name         | ID            | Count
--------------|---------------|---------------
 Alexander    | 12345         | 15
 Debra        | 23456         | 33
 Igor         | 54321         | 3

有几点值得注意:

  • 其中一个计数(但不是全部)立即不正确(从 34 变为 33)
  • 其中一行完全缺失

顾名思义,Count 行的计算方法是根据 COUNT(*) 语句对 SQL 查询中的其他元素进行计数。

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

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

try (PreparedStatement p = conn.prepareStatement(query,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)){

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

try (PreparedStatement p = conn.prepareStatement(query)) {

这个简单的更改导致 Java 结果集与 AquaData(和其他方法)结果集完全匹配。深入研究 Java 文档,似乎唯一有意义的更改是默认参数中的 TYPE_SCROLL_INSENSITIVE 参数改为 TYPE_FORWARD_ONLY;默认参数中的 CONCUR_READ_ONLY 参数未更改。

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

<小时/>

其他信息:

DB2 平台:Linux/Unix/Windows
DB2 版本*:10050700 2016 年 3 月 22 日 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

* 通过执行 select versionnumber, version_timestamp, versionbuildlevel from sysibm.sysversions order by 2 desc 获取。

最佳答案

TYPE_SCROLL_INSENSITIVE - ...对结果集底层数据的更改不敏感。这意味着应用程序或服务器可以自由地预取数据,而无需考虑数据在应用程序使用数据时是否可能发生变化。

TYPE_FORWARD_ONLY - ...其光标只能向前移动的对象。但是这些行是在使用时检索的。

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

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

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

关于java - 为什么将 ResultSetType 从 TYPE_SCROLL_INSENSITIVE 更改为 TYPE_FORWARD_ONLY 会更改 SQL 查询的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57416153/

相关文章:

java - 为什么不能创建没有花括号的 1 语句函数?

Java JDBC Postgres : Select with single quote

java - 获取连接的mysql数据库名(JDBC)

java - 这是在没有任何复杂性和精确结果的情况下比较 Java 中的两个文档的最佳方法

java - 无法将值传递给 Java 中的 ArrayList

hadoop - 如何使用JDBC与HIVE建立连接?

c# - 我可以仅通过配置更改来修复 DB2 查询超时吗?

sql - 我可以在 SQL 中的另一个 "With"中做一个内部 "With"吗?

linux - 如何在我的 64 位 RHEL6 上获取 libpam.so.0(32 位)?

java - Hibernate:在没有 Java 类的情况下保留 XML 值