Oracle JDBC實現存在BUG(ResultSet::setFetchSize())?

來源:互聯網
上載者:User

根據JDK JDBC文檔,ResultSet::setFetchSize()函數語義為 JDBC 驅動程式設定此 ResultSet 對象需要更多行時應該從資料庫擷取的行數。如果指定的擷取大小為零,則 JDBC 驅動程式忽略該值,隨意對擷取大小作出它自己的最佳猜測。預設值由建立結果集的 Statement 對象設定。擷取大小可以在任何時間更改。

但在實際使用Oracle JDBC驅動時,我們開發的程式發生了莫名的錯誤,總是會出現擷取到的取值與資料庫實際取值不一致的情形,經過仔細的測試與排查,我們發現是由於ResultSet::setFetchSize()函數調用導致的錯誤,在我們的測試環境中,Oracle JDBC預設為ResultSet設定的大小為10,如果我們將其改編為100,那麼一般會在擷取第11條記錄的第一個取值時發生獲得取值與資料庫實際取值不一致的問題,引發問題的語句如下:

 ResultSet equipRs = roleStat.executeQuery();
 if(equipRs.getFetchSize() < 20)
  equipRs.setFetchSize(20);

但如果我們調用Statement的setFetchSize()函數預先設定FetchSize為期望的值,則不會引發問題:

 roleStat.setFetchSize(20); // 調用Statement的setFetchSize()方法不會引發問題
 ResultSet equipRs = roleStat.executeQuery();

因此,我們懷疑這是Oracle JDBC實現的一個BUG,測試回合環境如下:
1. Oracle 10201_database_win32.zip 伺服器版本
2. JDBC為10201_database_win32安裝中Oracle10.2.0/Server/jdbc/lib/目錄下的class12.jar和ojdbc14.jar兩個版本都測試過

測試代碼:

public static void main(String[] aArgvs)
{
  try{
    String jdbcUrl = "jdbc:oracle:thin:@localhost:1521:orcl";
    Properties pros = new Properties();
    pros.setProperty("user", "test");
    pros.setProperty("password", "test");
    Connection conn = new oracle.jdbc.driver.OracleDriver().connect(jdbcUrl, pros);
    PreparedStatement volStat = conn.prepareStatement("SELECT m,n FROM m");
    PreparedStatement roleStat = conn.prepareStatement("SELECT m_c,m_f FROM mn WHERE n_c = ? AND n_f = ?");
    ResultSet volRs = volStat.executeQuery();
    volRs.setFetchSize(100);
    while(volRs.next())
    {
      long con = 1492; // VoltageLevel
      long frag = volRs.getLong(1);
      String uri = volRs.getString(2);
     
      System.out.print("[" + con + "," + frag + "]  " + uri + " : ");
     
      roleStat.setLong(1, con);
      roleStat.setLong(2, frag);
//    roleStat.setFetchSize(20); // 調用Statement的setFetchSize()方法不會引發問題
      ResultSet equipRs = roleStat.executeQuery();
      if(equipRs.getFetchSize() < 20) // 調用ResultSet的setFetchSize()方法會引發問題
        equipRs.setFetchSize(20);
      while(equipRs.next())
      {
        System.out.print("[" + equipRs.getLong(1) + "," + equipRs.getLong(2) + "]");
      }
      equipRs.close();
      System.out.println("");
    }
  }
  catch(Exception ex)
  {
    ex.printStackTrace();
  }
}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.