2009-06-04 61 views
1

假設我正在進行JDBC調用,並且已將數據從數據庫提取到ResultSet。但由於網絡問題,我失去了與數據庫的連接。連接損壞後ResultSet的行爲

Connection,StatementResultSet在DB中未關閉)。我仍然能夠遍歷ResultSet

回答

4

即使你可以,你也不應該這樣做,除非你正在編寫一個非常特定的jdbc驅動程序。在某些情況下,結果集根本不會構建。在其他(Oracle IIRC)中,您可以對其進行配置,使其僅從總數中提取給定數量的行。

但是,一般情況下,如果您失去連接,則有更多事情需要擔心,而不是想知道是否可以遍歷部分提取的resulst set對象。在這種情況下,經驗法則是

  1. 假設最差;
  2. 嘗試關閉結果集, 聲明和連接;即使 物理連接丟失, 也可能有資源,如內存 和主叫側文件句柄 需要處理掉;
  3. 如果可能,嘗試獲取新的 連接(要麼是一個新物理連接要麼是 ,要麼是連接池),並且 重新開始。

另外,作爲一個經驗法則,在事務中執行語句時,您不應該擔心部分失敗。丟棄並重新嘗試。

在一些極少數情況下,數據庫可以向您發送供應商特定的代碼(SQLException.getErrorCode()),它可以告訴您操作是否可以重試。 Oracle有一些特定的代碼(不記得它們)的情況下,當你做一個插入和一個獨特的約束已被違反。有時候這樣的失敗操作可能會重試,但這是廠商和業務特定的。

一般情況下,只需轉儲mauled結果集並重新開始。

3

我非常確定它完全取決於您的JDBC驅動程序如何處理它。它可能會在連接丟失之前緩衝所有結果。在連接丟失之前,它可能只緩衝了接下來的10個結果。即使所有結果都被緩衝了,驅動程序本身也可能會開始拋出異常,然後才能完成對緩衝結果的迭代。

就我個人而言,我認爲網絡中斷後的任何行爲都被認爲是未定義的。

1

通常,任何類型的「整個結果集」對象都不會完全構造,直到成功接收完整行集。例如,如果您在對象上具有NumberRecordsAffected之類的屬性,則它必須已收到所有行。

但是像GetFirstRow/GetNextRow這樣的可枚舉對象通常會一次帶來一大塊行,所以在當前緩衝區耗盡之前(如果它緩衝了任何行)並且它試圖從數據庫獲取下一行。

在這兩種情況下,我都希望拋出異常,但是IANAJDBCD(我不是jdbc開發人員)。