连接损坏后 ResultSet 的行为

Posted

技术标签:

【中文标题】连接损坏后 ResultSet 的行为【英文标题】:Behaviour of ResultSet after connection got corrupted 【发布时间】:2009-06-04 16:50:21 【问题描述】:

假设我正在进行 JDBC 调用,并且我已从数据库中获取数据到 ResultSet。但由于网络问题,我失去了与数据库的连接。

ConnectionStatementResultSet 未在 DB 中关闭)。我还能遍历ResultSet 吗?

【问题讨论】:

【参考方案1】:

即使可以,除非您针对非常特定的 jdbc 驱动程序进行编码,否则您不应该这样做。在某些情况下,根本不会构造结果集。在其他(Oracle IIRC)中,您可以对其进行配置,使其仅从总数中获取给定数量的行。

但是,一般来说,如果您失去连接,您需要担心的事情比想知道是否可以迭代部分获取的结果集对象要多。在这种情况下,经验法则是

    假设最坏的情况; 尝试关闭结果集, 陈述和联系;即使 物理连接丢失, 可能有内存等资源 和调用方的文件句柄 需要处理掉的; 如果可能,尝试获取新的 连接(无论是一个新的物理 一个或来自连接池)和 重新开始。

此外,根据经验,在事务中执行语句时,您不必担心部分失败。丢弃并重新尝试。

在极少数情况下,数据库可以向您发送供应商特定代码 (SQLException.getErrorCode()),该代码可以告诉您是否可以重试操作。当您执行插入并且违反了唯一约束时,Oracle 有一些特定代码(不记得它们)。有时可以重试此类失败的操作,但这取决于供应商和业务。

一般来说,只需转储损坏的结果集并重新开始。

【讨论】:

【参考方案2】:

我很确定这完全取决于您的 JDBC 驱动程序如何处理它。它可能在连接丢失之前缓冲了所有结果。在连接丢失之前,它可能只缓冲了接下来的 10 个结果。即使所有结果都已缓冲,驱动程序本身也可能在您完成对缓冲结果的迭代之前开始引发异常。

就个人而言,我认为网络中断后的任何行为都被认为是未定义的。

【讨论】:

【参考方案3】:

通常,在成功接收到完整的行集之前,不会完全构造任何类型的“整个结果集”对象。例如,如果您在对象上有一个像 NumberRecordsAffected 这样的属性,那么它一定已经接收到所有行。

然而,像 GetFirstRow/GetNextRow 这样的可枚举对象通常会一次关闭一大块行,因此在当前缓冲区耗尽(如果它缓冲任何行)并尝试获取之前,您不会知道连接已终止数据库的下一行。

在任何一种情况下,我都希望抛出异常,但 IANAJDBCD(我不是 jdbc 开发人员)。

【讨论】:

以上是关于连接损坏后 ResultSet 的行为的主要内容,如果未能解决你的问题,请参考以下文章

jdbc数据库连接在方法中,而且要返回statement 或resultset 在方法里关闭连接会怎么样?要怎么处理?

ResultSet 字段索引减一

ResultSet

查找 ResultSet 列数? [复制]

Gradle 的依赖缓存可能已损坏(这有时会在网络连接超时后发生。)

获取 java.sql.SQLException:ResultSet 关闭后不允许操作