连接损坏后ResultSet的行为

问题描述:

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

Connection,StatementResultSet在DB中未关闭)。我仍然能够遍历ResultSet

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

但是,一般情况下,如果您失去连接,则有更多事情需要担心,而不是想知道是否可以遍历部分提取的resulst set对象。在这种情况下,经验法则是

  1. 假设最差;
  2. 尝试关闭结果集, 声明和连接;即使 物理连接丢失, 也可能有资源,如内存 和主叫侧文件句柄 需要处理掉;
  3. 如果可能,尝试获取新的 连接(要么是一个新物理连接要么是 ,要么是连接池),并且 重新开始。

另外,作为一个经验法则,在事务中执行语句时,您不应该担心部分失败。丢弃并重新尝试。

在一些极少数情况下,数据库可以向您发送供应商特定的代码(SQLException.getErrorCode()),它可以告诉您操作是否可以重试。 Oracle有一些特定的代码(不记得它们)的情况下,当你做一个插入和一个独特的约束已被违反。有时候这样的失败操作可能会重试,但这是厂商和业务特定的。

一般情况下,只需转储mauled结果集并重新开始。

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

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

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

但是像GetFirstRow/GetNextRow这样的可枚举对象通常会一次带来一大块行,所以在当前缓冲区耗尽之前(如果它缓冲了任何行)并且它试图从数据库获取下一行。

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