2011-06-07 79 views
1

过去2-3天我遇到了一个问题。这似乎是一个小问题,但我一直无法抓住它。java中的突变结果集行为

问题在于代码中的resultset rs。 方法mergeTable中的while(rs.next())语句行为突然。这是第一次,在某些情况下,它会进入while循环,有时它不会,并且在某些情况下,当它进入while循环时,会突然抛出结果集耗尽异常。我搜索了一下,发现结果集可能已经被访问代码的其他线程关闭了。但是这是一个简单的独立Java应用程序,不是多线程的。

我也在照顾其他两个resultset,check和checktarget不会影响resultset rs。我正在关闭语句和结果集。 你可以看看代码,看看我是否错过了某些东西。

正在使用的两个数据库实例是10.180.22.93:1521:V3demo(称为源数据库)和10.180.22.93:1521:fusiondb(称为目标数据库)。 rs结果集来自源数据库。结果集检查和检查目标来自目标数据库。因此,结果集rs将来自源数据库的表A,结果集检查和checktarget将来自目标数据库的表A.

static String mergeTable() throws Exception { 
    String result = "ERROR"; 
    int error = 0; 
    String tableString = "<table " + tablename + ">"; 

    PreparedStatement preparedSelect = null; 
    PreparedStatement preparedSelectTarget = null; 
    Statement selectSourceStmt = null; 
    ResultSet checkTarget = null; 
    ResultSet rs = null; 
    try { 

     logger.println("===================================================================================="); 
     logger.println("Processing table:" + tablename); 
     System.out.println("===================================================================================="); 
     System.out.println("Processing table:" + tablename); 

     // Create query to fetch records from the source 
     String sourceQuery = "SELECT * FROM " + tablename; 
     if (owner.trim().equals("F1") || owner.trim().equals("C1") || owner.trim().equals("CM")) 
      sourceQuery = sourceQuery + " WHERE OWNER_FLG='" + owner + "'"; 

     // Get the result set 

     selectSourceStmt = source.createStatement(); 
     rs = selectSourceStmt.executeQuery(sourceQuery); 

     System.out.println(sourceQuery); 

     String selectSQL = "SELECT COUNT(*) FROM " + tablename + " WHERE "; 
     String selectSQLTarget = "SELECT * FROM " + tablename + " WHERE "; // ankush 

     ResultSetMetaData metaData = rs.getMetaData(); 

     List list = new ArrayList(); 
     List typesList = new ArrayList(); 

     for (int i = 1; i <= metaData.getColumnCount(); i++) { 
      String columnName = metaData.getColumnName(i); 
      list.add(columnName); // list contains the entire list of columns of the source 
      typesList.add(metaData.getColumnType(i)); 

     } 

     for (int i = 1; i < keys.length; i++) { 

      if (i == 1) { 
       selectSQL = selectSQL + " " + keys[i] + "= ?"; 
       selectSQLTarget = selectSQLTarget + " " + keys[i] + "= ?"; //ankush 
      } 

      else { 
       selectSQL = selectSQL + " AND " + keys[i] + "= ?"; 
       selectSQLTarget = selectSQLTarget + " AND " + keys[i] + "= ?"; //ankush 
      } 

     } 

     logger.println("Select SQL:" + selectSQL); 
     logger.println("selectSQLTarget:" + selectSQLTarget); //ankush 

     preparedSelect = target.prepareStatement(selectSQL); 
     preparedSelectTarget = target.prepareStatement(selectSQLTarget); //ankush 

     int updateCount = 0, insertCount = 0, errorCount = 0; 
     // rs contains the entire table snapshot of source based on the owner flag 
     if (rs != null) { 

      while (rs.next()) { 
       try { 
        int i, count; 

        // check if record exists or not; keys contain the values of primary columns specified in the.lst file 
        for (int j = 1; j < keys.length; j++) { 
         preparedSelect.setObject(j, rs.getObject(keys[j])); // for every single row in source, corresponding rows are fetched from target.Here, where clause is being prepared 

        } 

        ResultSet check = preparedSelect.executeQuery(); // check is the target resultset for the primary key values in current row of source resultset 

        check.next(); 

        count = check.getInt(1); // count gives the row/s fetched from target based on the values in source. 
        check.close(); 

        // check if record exists or not; keys contain the values of primary columns specified in the.lst file 
        for (int j = 1; j < keys.length; j++) { 
         // for every single row in source, corresponding rows are fetched from target.Here, where clause is being prepared 
         preparedSelectTarget.setObject(j, rs.getObject(keys[j])); 

        } 

        // check is the target resultset for the primary key values in current row of source resultset 
        checkTarget = preparedSelectTarget.executeQuery(); 

        checkTarget.next(); 

        // if record exists UPDATE CONDITION 
        if (true) { // if there is a record in target for a row in source, update target 
         String rowString = "<row>"; 
         String rowDiffFlag = "N"; 
         // if merge flag is Y 
         if (mergeFlag.equals("Y")) { 
          String colDiffFlag = ""; 
          String sourceColVal = ""; 
          String targetColVal = ""; 
          // list contains the column names 
          for (i = 0; i < list.size(); i++) { 
           System.out.println("value of i " + i); 
          } 
          i++; // ????? 

         } else { 
           logger.print("Did not update Record:"); 


         } 
         rowString = rowString + "</row>"; 

         if (rowDiffFlag.equals("Y")) { 
          tableString = tableString + rowString; 
         } 

        } else { // if there is no record in target for a row in source, insert into target 
         String sourceColVal = ""; 
         String rowString = "<row>"; 
         for (i = 0; i < list.size(); i++) { //looping through columns in a row 
          System.out.println("column " + i); 
          } 

         rowString = rowString + "</row>"; 
         tableString = tableString + rowString; 
        } 

       } catch (Exception e1) { 

        e1.printStackTrace(logger); 

       } 
      } 
     } 

    } catch (Exception e) { 

     e.printStackTrace(logger); 

    } finally { 
     preparedSelect.close(); 
     preparedSelectTarget.close(); 
     selectSourceStmt.close(); 
     checkTarget.close(); 
     rs.close(); 
    } 

    tableString = tableString + "</table>"; 
    formXmlString(tableString); 

    if (error == 0) result = "SUCCESS"; 

    return result; 
} 
+4

你能缩小你的问题吗?有人读完所有代码是不太可能的。 – musiKk 2011-06-07 10:11:38

+0

narrowed down..while可合并方法中的rs.next循环.. – 2011-06-07 10:51:16

回答

0

哦,我的,你在这里发生的事情太多了。我将HTML和JDBC代码混合在一起。这是一个坏主意。

数据库连接不是线程安全的。你说你注意确保你的ResultSets不会干扰,但这个错误表明不是。我会重构此代码以隔离持久性,并使每个事情变得更简单。这对我来说看起来是错误的,但我不愿意通过它来弄清楚为什么。

+0

我正在写入包含节点的文本文件,并且在数据库实例上的各个表(具有相同名称)的列上进行比较时决定节点。只是一个想法:准备好的陈述是干涉的,因为它们在同一张桌子上。 preparedSelect = target.prepareStatement(selectSQL); preparedSelectTarget = target.prepareStatement(selectSQLTarget); – 2011-06-08 06:17:00

0

您确定resultset耗尽异常在rs ResultSet上,而不在其他两个可能的ResultSets上:check和checkTarget?