Основы - устранение неполадок с подключением пула Hibernate/JDBC
Что такое ответственность Hibernate в отношении подключений к базе данных, которые она получает из базового пула подключений. Проверяет ли он, закрывается ли соединение до его использования? и если так получилось другое соединение из пула?
Ниже приведена информация об ошибках и подтверждении. Любые идеи о том, где я могу начать устранять эту проблему, будут очень полезны. И любые советы по настройкам драйвера SQL Server, которые мы используем.
из журнала Catalina:
04-Nov-2010 21:54:52.691 WARNING org.apache.tomcat.jdbc.pool.ConnectionPool.abandon Connection has been abandoned PooledConnection[ConnectionID:8]:java.lang.Exception
at org.apache.tomcat.jdbc.pool.ConnectionPool.getThreadDump(ConnectionPool.java:926)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:681)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:545)
at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:166)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:106)
из нашего журнала приложений:
2010-11-04 21:54:52,705 [tomcat-http--18] WARN util.JDBCExceptionReporter - SQL Error: 0, SQLState: 08S01
2010-11-04 21:54:52,707 [tomcat-http--18] ERROR util.JDBCExceptionReporter - Socket closed
2010-11-04 21:54:52,708 [tomcat-http--18] ERROR transaction.JDBCTransaction - JDBC rollback failed
java.sql.SQLException: Connection has already been closed.
at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:112)
at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:94)
at org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor.invoke(AbstractCreateStatementInterceptor.java:71)
at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:94)
at org.apache.tomcat.jdbc.pool.interceptor.ConnectionState.invoke(ConnectionState.java:132)
at $Proxy38.rollback(Unknown Source)
at org.hibernate.transaction.JDBCTransaction.rollbackAndResetAutoCommit(JDBCTransaction.java:217)
at org.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:196)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doRollback(HibernateTransactionManager.java:676)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:845)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:822)
at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:412)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:111)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
Конфигурация:
<Resource defaultAutoCommit="false" defaultReadOnly="false"
defaultTransactionIsolation="SERIALIZABLE"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
fairQueue="false" initialSize="10"
jdbcInterceptors="ConnectionState;StatementFinalizer"
jmxEnabled="true" logAbandoned="true" maxActive="100"
maxIdle="10" maxWait="30000"
minEvictableIdleTimeMillis="10000" minIdle="10"
name="com.ourcompany.ap.shoppingcart/datasource"
password="somePassword" removeAbandoned="true"
removeAbandonedTimeout="60" testOnBorrow="true"
testOnReturn="false" testWhileIdle="false"
timeBetweenEvictionRunsMillis="5000"
type="javax.sql.DataSource"
url="jdbc:sqlserver://approd\approd;databaseName=prod"
useEquals="false" username="AccessPointNet"
validationInterval="30000" validationQuery="SELECT 1"/>`
Ответы
Ответ 1
Что такое ответственность Hibernate в отношении подключений к базе данных, которые она получает из базового пула подключений.
Не так много, освобождая его, когда закрывается Session
.
Проверяет, закрывается ли соединение до его использования? и если так получилось другое соединение из пула?
Нет, Hibernate не проверяет правильность подключения (-ов) к подключению, если вы хотите.
Ниже приведена информация об ошибках и подтверждении. Любые идеи о том, где я могу начать устранять эту проблему, будут очень полезны.
Какой процесс вы выполняете в точности? Длинная транзакция? Это время ожидания? Что говорит Caused by:
? О трассе:
2010-11-04 21:54:52,705 [tomcat-http--18] WARN util.JDBCExceptionReporter - SQL Error: 0, SQLState: 08S01
2010-11-04 21:54:52,707 [tomcat-http--18] ERROR util.JDBCExceptionReporter - Socket closed
2010-11-04 21:54:52,708 [tomcat-http--18] ERROR transaction.JDBCTransaction - JDBC rollback failed java.sql.SQLException: Connection has already been closed.
Можете ли вы воспроизвести его детерминированным способом? Любая проблема с сетью?
И любые советы по настройкам драйвера SQL Server, которые мы используем.
Я добавил отличный ресурс о конфигурации Tomcat и пула соединений ниже. Однако это не относится к SQL Server.
Ресурсы
Ответ 2
У меня была аналогичная проблема, которая была решена путем увеличения значения removeAbandonedTimeout до более высокого числа. Проблема, с которой мы столкнулись, связана с запросом, который потребовал больше времени, чем вышеупомянутый тайм-аут.
Ответ 3
Обычно мы обходим это с помощью dbcp и предоставляем validationQuery при определении нашего источника данных. Затем dbcp проверит удобство объединения пулов, выдав этот запрос (и прозрачно воссоздав соединение, если он больше не будет работать), прежде чем возвращать их в приложение.
Отъезд http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html
для более подробной информации.
Ответ 4
В настоящее время я использую liquibase(v1.9)
в моем проекте, и когда changeSets работает против пустой схемы, это всегда занимает больше 60 секунд, что приводит к тому, что нить, отмеченная заброшенной, меня не волнует, увеличивая значение removeAbandonedTimeout
, но это единственное решение, которое я смог найти, чтобы предотвратить эту проблему; однако после того, как численность исходной схемы завершена, это редко возникает проблема, поэтому я возвращаю значение на 60 секунд.
Ответ 5
В прошлом я работал над проблемой, когда мы неправильно возвращали соединения обратно в пул. Таким образом, когда соединение было использовано и не было возвращено, вызов базы данных, когда он выходил из таймаута, генерирует исключение.
Мы смогли воспроизвести проблему, выполнив вызов в базе данных, ждали 8 часов (время истечения по умолчанию postgres) и попытались снова позвонить в базу данных. Он бросает одно и то же исключение каждый раз. Наше решение состояло в том, чтобы пересмотреть (или, еще лучше, добавить) стратегию управления соединениями.
Итак, чтобы подвести итог, действительно ли вы возвращаете свои соединения в пул, закрывая сеанс?
Ответ 6
Я получил решение для вышеупомянутого исключения.
Просто закройте экземпляр сеанса factory, а также при закрытии сеанса.
Посмотрите на приведенный ниже код:
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
}
catch (Throwable ex) {
ex.printStackTrace();
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionfactory() {
return sessionFactory;
}
public static Session getSession() {
Session session=sessionFactory.openSession();
session.getTransaction().begin();
return session;
}
public static void closeSession(Session session) {
if(session!=null )
{
if(session.getTransaction().isActive())
{
session.getTransaction().commit();
}
session.close();
getSessionfactory().close();
}
}
}
просто вызовите метод HibernateUtil.closeSession(). Это решит проблему.