1

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

( Connection,Statement并且ResultSet未在 DB 中关闭)。我仍然可以迭代ResultSet吗?

4

3 回答 3

4

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

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

  1. 假设最坏的情况;
  2. 尝试关闭结果集、语句和连接;即使物理连接丢失,调用端的内存和文件句柄等资源也可能需要处理掉;
  3. 如果可能,尝试获取新连接(新的物理连接或连接池)并重新开始。

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

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

通常,只需转储损坏的结果集并重新开始。

于 2010-04-02T16:24:18.090 回答
3

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

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

于 2009-06-04T17:03:43.290 回答
1

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

但是,像 GetFirstRow/GetNextRow 这样的可枚举对象通常会一次删除一大块行,因此在当前缓冲区耗尽(如果它缓冲任何行)并尝试获取下一行之前,您不会知道连接已终止从分贝。

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

于 2009-06-04T20:02:39.153 回答