Будет ли закрытие подготовленного оператора также закрывать и возвращать соединение в пул соединений?

public void insertProjectIntoDatabase(Project project) {
        String insertProjectIntoDatabase =
                "INSERT INTO projects(Project_Id, Project_Name, Project_StartDate, Deadline) " +
                        "VALUES (?, ?, ?, ?)";
        try {
            preparedStatement = DBCPDataSource.getConnection().prepareStatement(insertProjectIntoDatabase);
            preparedStatement.setInt(1, project.getProjectId());
            preparedStatement.setString(2, project.getName());
            preparedStatement.setDate(3, java.sql.Date.valueOf(project.getStartDate()));
            preparedStatement.setDate(4, java.sql.Date.valueOf(project.getDeadline()));
            preparedStatement.execute();

            preparedStatement.close();
        }
        catch (SQLException e)
        {
            System.out.println("Error happened in ProjectRepository at insertProjectIntoDatabase(): " + e.getMessage());
        }
    }

Бонусный вопрос:

Я создал тесты производительности для создания нового соединения каждый раз, когда оно требуется объекту, одноэлементное соединение и пул соединений.

Синглтон - самый быстрый

Создание нового соединения каждый раз - медленнее (на 1,2 секунды, чем указанное выше)

Пул подключений - самый медленный (первое подключение - на 2-3 секунды медленнее, чем показанное выше, последующие тесты на 0,4 секунды медленнее, чем показанное выше)

Я использую Apache Commons DBCP для пула соединений.

Я думал, что использование пулов соединений будет немного медленнее, чем соединение Singleton.

Я сделал что-то не так?

0
Frederik Meizner Petersen 23 Янв 2021 в 20:43

2 ответа

Лучший ответ

Ты спрашивал:

Будет ли закрытие подготовленного утверждения также закрывать и возвращать соединение в пул соединений?

Начните с документация:

Освобождает базу данных этого объекта Statement и ресурсы JDBC немедленно, вместо того, чтобы ждать, пока это произойдет, когда он автоматически закроется. Обычно рекомендуется освобождать ресурсы, как только вы закончите с ними, чтобы не связывать ресурсы базы данных.

Вызов метода close для уже закрытого объекта Statement не имеет никакого эффекта.

Примечание. Когда объект Statement закрывается, его текущий объект ResultSet, если он существует, также закрывается.

Никакого упоминания о закрытии соединения.

Попробуйте интуицию: выполняем ли мы когда-нибудь более одного оператора в SQL? Да, конечно.

И наконец: попробуйте. Вызов Connection#isOpen после вызова Statement#close.

➥ Нет, закрытие оператора не приводит к закрытию соединения.

Чтобы получить самый простой код, научитесь использовать try-with-resources синтаксис для автоматического закрытия ресурсов базы данных, таких как набор результатов, оператор и соединение. На этом сайте вы найдете множество примеров такого кода, в том числе написанные мной.

Что касается пулов соединений, да, вызов close для соединения, полученного из пула, будет возвращен в пул. Пул может выбрать повторное использование соединения или его закрытие. (Это не наша забота.)

Единственная особенность пула подключений - это скорость. Если открытие подключения к базе данных занимает значительное время, мы можем сэкономить это время, повторно используя существующее подключение. Создание и повторное использование соединений - это задача пула соединений.

Если пул соединений показывает самые медленные результаты в вашем тестировании, то здесь что-то серьезно не так с вашим пулом или вашими тестами. Вы не открыли нам свои тесты, поэтому мы не можем здесь помочь. Примечание: как Marmite Bomber прокомментировал убедитесь, что ваши тесты не включают время, необходимое для установления пула соединений.

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

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

2
Basil Bourque 23 Янв 2021 в 19:24

Пулы предназначены для повышения производительности, а не для ее снижения. DBCP наивен, сложен и устарел. Я не думаю, что это подходит для производственного приложения, особенно когда так много драйверов изначально поддерживают пул в своих источниках данных. Весь пул блокируется все время, когда делается новая попытка подключения к базе данных. Итак, если что-то происходит с вашей базой данных, что приводит к медленным соединениям или тайм-аутам, другие потоки блокируются, когда они пытаются вернуть соединение с пулом, даже если они выполняются с использованием базы данных. Даже C3PO работает ужасно. Попробуйте использовать один из двух пулов подключений tomcat_connection_pool или < a href = "https://www.baeldung.com/hikaricp" rel = "nofollow noreferrer"> HikariCP

Теперь переходим к основной части вопроса, правильно ли вы закрыли соединение? Каждый раз, когда вы используете пул соединений и получаете доступное соединение из пула, вам не нужно закрывать соединение, которое вы выбрали на уровне Dao. Пул управляет созданными вами соединениями, и каждое соединение, которое предоставляет пул, имеет связанный с ним тайм-аут, до которого он должен вернуться в пул. Когда пул закрывается, все соединения тоже закрываются.

Для получения дополнительной информации о том, как настроить эти свойства в пуле соединений. Пожалуйста, проверьте ссылки выше для каждого из пулов подключений.

1
Melroy Dsouza 23 Янв 2021 в 18:53
65862398