Как исправить «SQLServerException: соединение закрыто».вхождение в этом блоке Try-With-Resources? - PullRequest
0 голосов
/ 22 мая 2019

Я делаю тестирование производительности СУБД.Я должен сделать это вручную для моей магистерской диссертации.У меня должно быть определенное количество потоков, каждый из которых открывает свое собственное JDBC-соединение с БД (пул соединений не является опцией) и фиксирует одинаковое количество одинаковых транзакций (каждый поток выполняет одну и ту же работу).Мое соединение открыто как ресурс в блоке try-with-resources.Соединение должно оставаться открытым до конца области действия try-with-resources, но иногда это происходит, а иногда нет.

try (Connection conn = getConn();
    PreparedStatement simpleSelectStmt = conn
                         .prepareStatement(tcInstance.getQueryMap().get("SimpleSelect").getSimpleSelect())) {

        setConnIsolation(conn);

        long startTime = System.nanoTime();
        singleThread.execute(new Runnable() {

            @Override
            public void run() {

                for (int j = 0; j < tcInstance.getnT(); j++) {
                    try {
                        conn.setAutoCommit(false);
                        simpleSelectStmt.execute();
                        conn.commit();
                    } catch (Exception e) {
                        error++;
                        if (detectDeadlock(e.getMessage())) {
                            deadlock++;
                            System.out.println("Deadlock detected!");
                        } else {
                            e.printStackTrace();
                        }

                        try {
                            if (conn != null) {
                                conn.rollback();
                            }
                        } catch (SQLException e1) {
                            System.out.println("There was an error in rolling back the transaction.");
                            e1.printStackTrace();
                        }

                    }

                    if (j != (tcInstance.getnT() - 1)) {
                        try {
                            Thread.sleep(t);// ms
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }

                measureCPUusage(Thread.currentThread().getId());
                singleThread.shutdown();

        });

        long endTime = System.nanoTime();
        ....doing some other measurements....

    } catch (Exception e) {
        System.err.println("Error");
    }

Это метод getConn(), используемый для получения соединения jdbc:

private Connection getConn() throws SQLException {
    return DriverManager.getConnection(tcInstance.getJDBCurl(), tcInstance.getUser(), tcInstance.getPassword());
}

Я ожидал, что соединение будет открыто через весь блок try-with-resources, но тамСоединение закрыто исключениями на линиях conn.setAutoCommit(false); и conn.rollback();

Ответы [ 2 ]

1 голос
/ 22 мая 2019

Вкратце, ваш поток кода выглядит примерно так:

try (Connection conn = getConn()) {
    setConnIsolation(conn);

    // Posted from Thread-1
    singleThread.execute(new Runnable() {

        @Override
        public void run() {

        // Thread-2 accesses conn created on Thread-1
        // use conn here..
    });

   // ....doing some other work....

} catch (Exception e) {
    System.err.println("Error");
}

//Conn is released

К тому времени, когда runnable начинает свою работу, его соответствующий поток может использовать освобожденный conn.Это связано с тем, что поток публикации после публикации исполняемого файла выходит из блока Try-With-Resources и как его часть освобождается Conn.

Решение: вывести Conn из попытки-Блок ресурсов.

0 голосов
/ 22 мая 2019

Пожалуйста, откройте отдельное соединение для каждой темы.Ваше открытое соединение для одного потока закрывается другим потоком, и, следовательно, вы получаете исключение. Также, пожалуйста, предоставьте больше информации о detectDeadlock, чтобы помочь вам в дальнейшем.Я надеюсь, что вам не нужны такие вещи для простых соединений в многопоточных средах.

...