Closing JDBC Connections in Pool

Refresh

November 2018

Views

76.6k time

96

Our standard code section for using JDBC is...

Connection conn = getConnection(...);
Statement  stmt = conn.conn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
                                                ResultSet.CONCUR_READ_ONLY);
ResultSet  rset = stmt.executeQuery (sqlQuery);

// do stuff with rset

rset.close(); stmt.close(); conn.close();

Question 1: When using Connection Pool, should one close the Connection at the end? If so, isn't the purpose of pooling lost? And if not, how does the DataSource know when a particular instance of Connection is freed up and can be reused? I am a little confused on this one, any pointers appreciated.

Question 2: Is the following method anything close to standard? Looks like an attempt to get a connection from the pool, and if DataSource cannot be established, use the old fashioned DriverManager. We are not even sure which part is getting executed at runtime. Repeating the question above, should one close the Connection coming out of such a method?

Thank you, - MS.

synchronized public Connection getConnection (boolean pooledConnection)
                                                        throws SQLException {
        if (pooledConnection) {
                if (ds == null) {
                        try {
                                Context envCtx = (Context)
                                        new InitialContext().lookup("java:comp/env");
                                ds = (DataSource) envCtx.lookup("jdbc/NamedInTomcat");
                                return ds.getConnection();
                        } catch (NamingException e) {
                                e.printStackTrace();
                }}
                return (ds == null) ? getConnection (false) : ds.getConnection();
        }
        return DriverManager.getConnection(
                "jdbc:mysql://"+ipaddy+":"+dbPort +"/" + dbName, uName, pWord);
}

Edit: I think we are getting the pooled connection since we do not see a stack trace.

3 answers

21

Бассейны обычно возвращают вам обернутый объект Connection, где метод Close () переопределяется, как правило, возвращаются подключения к бассейну. Вызов близко () в порядке и, вероятно, все еще требуется.

Метод близко (), вероятно, выглядеть следующим образом:

public void close() throws SQLException {
  pool.returnConnection(this);
}

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

0

На самом деле, лучший подход к управлению соединением, чтобы не возделывать их к какому-либо коду в любом месте.

Создайте класс SQLExecutor, который является один и только место, которое открывает и закрывает соединение.

Вся остальная часть приложения, то насосы заявления в исполнителю, а не получать соединения из пула и управления (или неумело их) повсюду.

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

Удобно, это также позволяет регистрировать весь ваш SQL из одного набора кода.

106

При использовании пула соединений, следует закрыть соединение в конце? Если да, то это не является целью аккумулирования потерял? И если нет, то как же DataSource знать, когда конкретный экземпляр Connection освобождается и может быть повторно? Я немного запутался на этом, любые указатели оценили.

Да, конечно , вы должны закрыть пул подключения , а также. Это на самом деле обертка вокруг фактического соединения. Это Виль под одеяло освободить фактическое соединение обратно в бассейн. Это дополнительно к бассейну , чтобы решить , будет ли фактическое соединение будет фактически закрыто или повторно использовать для нового getConnection()вызова. Таким образом, независимо от того, используете ли вы пул соединений или нет, вы должны всегда закрывать все ресурсы JDBC в обратном порядке в finallyблоке tryблока , в котором вы приобрели их. В Java 7 это может быть дополнительно упрощена с помощью try-with-resourcesзаявления.


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

Пример довольно страшно. Вам просто нужно для поиска / инициализировать DataSourceтолько один раз при запуске приложения в какой - то конструктор / инициализации в applicationwide DB класса конфигурации. Тогда просто позвоните getConnection()по одному и тому же источнику данных на протяжении всего остального времени жизни приложения. Нет необходимости в синхронизации ни nullchecks.

Смотрите также: