连接损坏后ResultSet的行为

时间:2009-06-04 16:50:21

标签: java sql jdbc resultset

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

ConnectionStatementResultSet未在DB中关闭。我仍然可以迭代ResultSet吗?

3 个答案:

答案 0 :(得分:4)

即使你可以,你也不应该,除非你正在编写一个非常具体的jdbc驱动程序。在某些情况下,结果集根本不会构建。在其他(Oracle IIRC)中,您可以对其进行配置,使其仅从总数中提取给定的行数。

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

  1. 假设最坏的;
  2. 尝试关闭结果集, 陈述和联系;即使 物理连接丢失, 可能有像记忆这样的资源 和调用端的文件句柄 需要处理的;
  3. 如果可能的话,尝试获得一个新的 连接(要么是新的物理连接 一个或来自连接池)和 重新开始。
  4. 另外,根据经验,在执行事务中的语句时,您不必担心部分失败。丢弃并重新尝试。

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

    通常,只需转储已填妥的结果集并重新开始。

答案 1 :(得分:3)

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

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

答案 2 :(得分:1)

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

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

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