#java #oracle #tomcat #connection-pooling
#java — язык #Oracle #кот #объединение в пул соединений #java #tomcat #соединение-объединение в пул
Вопрос:
Я использую пул соединений tomcat с базой данных Oracle. Это работает нормально, но когда я использую свое приложение после долгого времени, оно выдает ошибку «сброс соединения«. Я получаю эту ошибку из-за того, что физическое соединение на сервере Oracle закрыто до того, как логическое соединение закрыто в источнике данных tomcat. Итак, перед получением соединения из источника данных я проверяю действительность соединения с помощью метода isValid (0) объекта connection, который выдает false, если физическое соединение было закрыто. Но я не знаю, как удалить этот объект недопустимого соединения из пула.
Ответ №1:
Это может быть связано с тем, что на сервере БД существует тайм-аут, чтобы не позволять подключениям работать дольше установленного времени или прерываться, если он не получит сообщение о том, что оно все еще действует. Один из способов исправить это — включить keepalives. Они в основном проверяют сервер БД, сообщая, что они все еще являются допустимыми соединениями.
Это довольно хорошая ссылка на конфигурации Tomcats DBCP. Взгляните на раздел, озаглавленный «Предотвращение утечек пула соединений с БД». Похоже, что это может быть хорошим местом для начала.
Комментарии:
1. Да, я сталкивался с этим раньше. Вы можете настроить пул подключений на проверку наличия нерабочих соединений с помощью SQL-запроса (validationQuery) с указанным интервалом. Это часть конфигурации DBCP. Вы хотите избежать проверки в своем коде, поскольку ваш код не должен знать о объединении в пул или конкретной базе данных.
2. Я уже настроил его, но когда я вызываю con.isValid(), это ничего не дает.
3. @cjstehno да, я согласен. Вы не должны проверять состояние соединений в вашем пуле в коде. Какой тип пула вы используете?
4. общедоступное статическое соединение getConnection(){ Connection con = null; try{ if(ds == null) loadDataSource(); con = ds.getConnection(); }catch (Исключение e){ e.printStackTrace(); выдает новое исключение DBUtilException(«Не удается получить объект подключения к базе данных. Причина: » e.GetMessage()); } возвращает con; } Что мне нужно сделать.
5. вероятно, вы не хотите публиковать свой dbs: URL, имя пользователя и пароль. Вероятно, вы хотите отредактировать свой комментарий или изменить его на своем сервере.
Ответ №2:
Я использовал validatationquery при настройке источника данных в server.xml файл. Он собирается проверить действительность соединения, выполнив запрос в базе данных перед отправкой приложению.
для Oracle
validationQuery="/* select 1 from dual */"
для MySQL
validationQuery="/* ping */"
Ответ №3:
Попробуйте закрыть его и открыть, если оно недопустимо. Я имею в виду, что вы бы повторно инициализировали его таким образом, чтобы вам не нужно было удалять его из пула и повторно использовать.
Комментарии:
1. if(!con.isValid(30)){ con.close(); con = ds.getConnection(); } Кто знает, является ли второе допустимым.
2. con = ds.getConnection(); if (!con.isValid(30)) con = ds.getConnection(); верните con; Если я поступлю подобным образом, я получу новое соединение из пула, и я возвращаю это новое соединение месту вызова, и эта функция закрывает соединение после использования. Здесь я не возвращаю недопустимое соединение, чтобы через некоторое время оно прекратило то, что я настроил в файле конфигурации пула (server.xml/context.xml )
Ответ №4:
Если мы хотим удалить некорректное java.sql.connection из пула соединений Tomcat jdbc,
мы можем сделать это явно в программе. Разверните его в org.apache.tomcat.jdbc.pool.PooledConnection, установите значение Discarded (true) и окончательно закройте соединение JDBC. ConnectionPool удалит базовое соединение, как только оно будет возвращено.
(ConnectionPool.returnConnection(….))
например, PooledConnection pconn = conn.unwrap(PooledConnection.class ); pconn.setDiscarded(true); conn.close();