Сколько раз я должен закрывать соединение в SQL? - PullRequest
0 голосов
/ 16 декабря 2009

У меня в классе баз данных много методов, у которых у всех один оператор, когда мне закрывать соединение? В каждом методе или в конце класса базы данных?

Ответы [ 11 ]

6 голосов
/ 16 декабря 2009

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

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

3 голосов
/ 16 декабря 2009

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

1 голос
/ 16 декабря 2009

используйте lombok, и он будет обрабатывать как try / catch, так и conn.close () для вас


public void doSomething() throws SQLException {

@Cleanup Connection connection = database.getConnection();
}

Ломбок

1 голос
/ 16 декабря 2009

Как правило, вы должны закрывать соединение тем же способом, который его открывает. Закрытие и открытие соединений не является сложной задачей, поскольку современные серверы БД поддерживают даже закрытые соединения в «горячем резерве», поэтому к ним можно быстро получить доступ через пул соединений. Оставив их открытыми, хотя ... это может привести к неприятностям и может стать кошмаром для отладки.

1 голос
/ 16 декабря 2009

Рекомендуется закрывать соединение в логическом месте после завершения - сразу после выполнения всех действий с базой данных для этой задачи.

0 голосов
/ 17 декабря 2009

Это в некоторой степени зависит от контекста, в котором работает ваше приложение. Если это веб-приложение, вам нужно быть осторожным, чтобы открыть соединение, выполнить любую необходимую работу и быстро закрыть соединение. Однако в среде C / S или пакетной среде может быть лучше получить соединение и удерживать его, пока пользователь взаимодействует «часто» (при любом значении «часто», которое вы выбираете), особенно если у пользователя есть ожидания быстрое время отклика и дорогостоящее (с точки зрения времени или ресурсов) подключение к вашей конкретной базе данных.

Мне нравится устанавливать таймер каждый раз, когда пользователь отправляет приложение в базу данных. Если / когда таймер истекает, закройте соединение, а затем снова откройте в следующий раз, когда он / она / она хочет снова обратиться к базе данных. Время истечения таймера может быть где-то между 1 и 20 минутами. До тех пор, пока оно меньше времени отключения базы данных.

Делись и наслаждайся.

0 голосов
/ 16 декабря 2009

Если это опция, вообще не связывайтесь с соединениями. Используйте полноценный фреймворк orm, например, hibernate, или используйте что-то значительно более легкое, например шаблоны jdbc для Spring.

0 голосов
/ 16 декабря 2009

Всегда закрывайте соединение, когда завершаете выполнение транзакции. Хорошей практикой является получение и закрытие соединения одним и тем же способом. Если у вас есть отдельные транзакции, которые тесно связаны между собой, вы можете выполнить их с тем же соединением, но для наилучшей практики я пытаюсь выполнить одну транзакцию на соединение.

0 голосов
/ 16 декабря 2009

Закройте соединение (и оператор и набор результатов!) В том же блоке метода , в котором вы его получили, в блоке finally блока try, где они открыты.

Общая идиома:

public void doSomething() throws SQLException {
    Connection connection = null;
    try {
        connection = database.getConnection();
    } finally {
        if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
    }
}

Закрытие соединения, оператора и набора результатов должно происходить в обратном порядке по мере их открытия.

Если реальная проблема связана с производительностью, рассмотрите возможность использования пула соединений для повышения производительности соединения, например C3P0 . Это, кстати, не меняет общую идиому. Просто продолжайте писать ту же идиому, реализация пула подключений будет волновать себя еще больше.

Также см. эту статью для получения дополнительной практики / примеров.

0 голосов
/ 16 декабря 2009

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

Самое главное, что где бы вы ни открывали соединение, вы также закрываете соединение. В противном случае вы начнете делать предположения о состоянии соединения, что может привести к неприятностям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...