Резкое поведение набора результатов в java

Я застрял с проблемой за последние 2-3 дня. Кажется, это незначительная проблема, но я не смог ее поймать.

Проблема связана с набором результатов rs в коде. Инструкция while (rs.next()) в методе mergeTable ведет себя резко. Впервые в некоторых случаях он входит в цикл while, иногда нет, а в нескольких случаях, когда он входит в цикл while, он внезапно выдает исчерпанное исключение результирующего набора. Я погуглил и обнаружил, что набор результатов мог быть закрыт каким-то другим потоком, обращающимся к коду. Но это простое автономное Java-приложение, не являющееся многопоточным.

Я также слежу за тем, чтобы два других набора результатов, check и checktarget, не мешали набору результатов rs. Я также закрываю операторы и наборы результатов. Можете ли вы взглянуть на код и посмотреть, не упускаю ли я что-то.

Используются два экземпляра базы данных: 10.180.22.93:1521:V3demo (называется исходной базой данных) и 10.180.22.93:1521:fusiondb (называется целевой базой данных). Набор результатов rs взят из исходной базы данных. Наборы результатов check и checktarget взяты из целевой базы данных. Таким образом, набор результатов rs будет из таблицы A из исходной базы данных, а наборы результатов check и 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;
}

person Ankush Mehta    schedule 07.06.2011    source источник
comment
Можете ли вы сузить вашу проблему? Маловероятно, что кто-то прочитает весь этот код.   -  person musiKk    schedule 07.06.2011
comment
сузился.. в то время как цикл rs.next в методе слияния..   -  person Ankush Mehta    schedule 07.06.2011


Ответы (2)


О, Боже, у тебя здесь слишком много всего происходит. Я вижу смешанный код HTML и JDBC. Это плохая идея.

Соединения с базой данных не являются потокобезопасными. Вы говорите, что заботитесь о том, чтобы ваши ResultSet не мешали, но эта ошибка говорит об обратном. Я бы реорганизовал этот код, чтобы изолировать постоянство и упростить все. Это просто кажется мне неправильным, но я не хочу вникать в это, чтобы понять, почему.

person duffymo    schedule 07.06.2011
comment
Я пишу в текстовый файл с узлами, и узлы определяются на основе сравнения, выполняемого в отдельных столбцах таблиц (имеющих одинаковое имя) в экземплярах базы данных. Просто мысль: мешают ли подготовленные операторы, поскольку они находятся в одной таблице . подготовленный выбор = target.prepareStatement (selectSQL); подготовленныйSelectTarget = target.prepareStatement(selectSQLTarget); - person Ankush Mehta; 08.06.2011

Вы уверены, что исчерпанное исключение результирующего набора находится в rs ResultSet, а не в двух других возможных ResultSet: check и checkTarget?

person Sébastien Nussbaumer    schedule 07.06.2011