Основы - Устранение неполадок в пуле соединений Hibernate / JDBC - PullRequest
15 голосов
/ 05 ноября 2010

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

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

из журнала Каталины:

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"/>`

Ответы [ 6 ]

17 голосов
/ 06 сентября 2012

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

14 голосов
/ 07 ноября 2010

Какую ответственность несет 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 голосов
/ 13 марта 2014

В настоящее время я использую liquibase(v1.9) в своем проекте, и когда набор изменений запускается с пустой схемой, это всегда занимает больше 60 секунд, что приводит к тому, что поток помечается как отказавшийся., но это единственное решение, которое я смог найти, чтобы предотвратить эту проблему;однако после завершения первоначального заполнения схемы это редко становится проблемой, поэтому я возвращаю значение 60 секунд.

2 голосов
/ 05 ноября 2010

Обычно мы обходим это, используя dbcp и предоставляя validationQuery при определении нашего источника данных.Затем dbcp проверит удобство использования соединений в пуле, выполнив этот запрос (и прозрачно воссоздаст соединение, если оно больше не работает), прежде чем вернуть их в приложение.

Извлечь http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html дляболее подробная информация.

1 голос
/ 05 ноября 2010

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

Мы смогли воспроизвести проблему, сделав вызов в базу данных, подождав 8 часов (установленное по умолчанию время ожидания postgres) и снова попытался позвонить в базу данных.Это бросает одно и то же исключение каждый раз.Нашим решением было переосмыслить (или еще лучше добавить ) стратегию управления соединениями.

Итак, подведем итог: вы действительно возвращаете свои соединения в пул, закрывая сеанс?

0 голосов
/ 29 декабря 2014

Я получил решение для вышеуказанного исключения.Просто закройте экземпляр фабрики сессий при закрытии сессии.

Посмотрите на приведенный ниже код:

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 () ,Это решит проблему.

...