WebApp (Tomcat-jdbc) Соединение с базой данных в пуле, выбрасывающее исключение

Я просматривал ПО в течение некоторого времени и жевал свою шляпу в процессе, но не могу найти точное соответствие своей проблеме.

Для краткости я получаю превосходную трассировку стека (org.apache.tomcat.jdbc.pool.ConnectionPool отказаться) после 60 секунд бездействия, что является нормальным поведением для пары потоков на стороне сервера.

Я использую пул соединений Tomcat JDBC (org.apache.tomcat.jdbc.pool.DataSource) напрямую

Трассировки стека:

    Oct 29, 2012 8:55:50 PM org.apache.tomcat.jdbc.pool.ConnectionPool abandon
    WARNING: Connection has been abandoned PooledConnection[[email protected]]:java.lang.Exception
        at org.apache.tomcat.jdbc.pool.ConnectionPool.getThreadDump(ConnectionPool.java:967)
        at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:721)
        at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:579)
        at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:174)
        at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:111)
        at com.getsom.getConnection(DAO.java:1444)
        at com.getsom.PreparedConnection.(PreparedConnection.java:48)
        at com.getsom.Alarms.run(Alarms.java:492)

Мои PoolProperties настроены следующим образом:

    PoolProperties pp = new PoolProperties();

    pp.setUrl( someValidUrl);
    pp.setDriverClassName("com.mysql.jdbc.Driver");
    pp.setUsername( someUser);
    pp.setPassword( somePassword);
    pp.setJmxEnabled( true);
    pp.setTestWhileIdle( true);
    pp.setTestOnBorrow( true);
    pp.setValidationQuery( "SELECT 1");
    pp.setTestOnReturn( false);
    pp.setValidationInterval(30000);
    pp.setTimeBetweenEvictionRunsMillis(30000);
    pp.setMaxActive(100);
    pp.setInitialSize(10);
    pp.setMaxWait(10000);
    pp.setMinEvictableIdleTimeMillis(30000);
    pp.setMinIdle(10);

    pp.setLogAbandoned(true);
    pp.setRemoveAbandoned(true);
    pp.setRemoveAbandonedTimeout(60);
    pp.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
      "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");    

    setPoolProperties(pp);

Я надеялся, что setValidationInterval (30000) спасет меня, поскольку 30-е годы не так много в жизненном цикле соединения. Во всяком случае, вопрос:

Чего мне не хватает, чтобы сохранить эту связь навсегда?

Приятно знать: почему я отключил функцию, которая требовала подключения, хотя она была вызвана 30 секундами ранее.

Ответы на вопрос(7)

т. Е. Tomcat закрывал соединение JDBC из-за того, что оно было прервано, потому что транзакция занимала много времени.

Решил это, осознав, чтоabandoned а такжеidle различаются и путем установки:spring.datasource.tomcat.removeAbandonedTimeout: 86400 #seconds

имально запущенный запрос в приложении. иначе он закроет соединение в середине исполнения

 John Little06 авг. 2015 г., 19:18
У меня та же проблема, и уже есть набор removeAbandonedTimeout, и, к сожалению, это не помогает.
 Navigatron15 мар. 2016 г., 11:35
Можете ли вы объяснить, какотслеживать» этот атрибут ресурса в Tomcat?

xml, где присутствует ваш тег ресурса.

jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;
org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer"

Хотя в моем случае у меня уже было "ResetAbandonedTimer» Перехватчик JDBC настроен.

Тем не менее, у меня был запрос, который работал дольше, чем "removeAbandonedTimeout» что я тоже настроил. Однажды я увеличилremoveAbandonedTimeout» проблема ушла.

PoolConnection, Возможно, вам нужно посмотреть на имуществоminEvictableIdleTimeMillis

Чтобы ответить на ваш вопрос, у вас тайм-аут, потому что вы проверяете на бездействие и прекращать соединения каждые 30 секунд (см.TimeBetweenEvictionRunsMillis) и так как вы устанавливаете время ожидания простоя на 30 секунд (см.minEvictableIdleTimeMillis) тогда вы в конечном итоге с тем, что у вас есть. Вы сказали, что получаете это исключение во время простоя, я подозреваю, что исключение является результатом закрытия простаивающего соединения, а не отказа от соединения. Насколько я понимаю, отказ от соединения используется для тайм-аута дольше ожидаемых запросов (в отличие от незанятых соединений).

Лично я не хотел бы, чтобы соединения были живы вечно, потому что они потребляли бы ресурсы (то есть соединение с БД) без необходимости. Я бы поиграл с моими максимальными связями, прогонами выселения и простоями, чтобы оптимизировать под свои собственные требования Я думаю, вы можете установить эти значения достаточно большими, чтобы быть почти навсегда! Это действительно зависит от того, что вы делаете, хотя ...

Извините я не смогтут гораздо больше поможет.

 MonoThreaded31 окт. 2012 г., 11:26
Надежда бесценна :)
 MonoThreaded30 окт. 2012 г., 12:41
Нету. Рассматриваемая тема простаивает. В чем проблема, поскольку ConnectionPool предполагает, что соединение разорвано.
 ramsinb30 окт. 2012 г., 12:04
Получаете ли вы ошибку при выполнении запроса? Может показаться странным, что ваш запрос выполняется дольше 60 секунд!
 ramsinb30 окт. 2012 г., 21:35
отредактировал мой ответ, но чувствую, что у меня нетЯ действительно очень тебе помог ...
 MonoThreaded30 окт. 2012 г., 09:18
Да, я много читал об этом. Я считаю, что это связано с отказом от более чем выселения. Я предполагал, что ConnectionPool будет поддерживать эти соединения живыми.
 Mate Šimović02 мар. 2019 г., 13:02
Если у вас есть проблемы сотказались» а не схолостой ход» соединения, попробуйте установить (решенная проблема для меня): spring.datasource.tomcat.removeAbandonedTimeout: 86400 #seconds
Решение Вопроса

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

В моем случае после нахождения и прочтения этой статьи >>> конфигурированию-JDBC-бассейн с высоким параллелизмом - Я просто добавил такой перехватчик в конфигурацию пула;

"org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer"

так что строка (из вашего кода выше), где вы делаетеsetJdbcInterceptors(...) теперь должен выглядеть следующим образом;

p.setJdbcInterceptors(
            "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
            + "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;"
            + "org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer");

объяснение - цитируя статью, там написано;

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

Каждый раз, когда оператор готовится или выполняется запрос, таймер сбрасывает таймер отмены в пуле соединений. Таким образом ... делать много запросов и обновлений, не будет тайм-аут.

Учитывая, что вы, скорее всего, уже давно преодолели эту проблему, я все еще надеюсь, что это поможет всем, кто сталкивается с подобными проблемами, которые сталкиваются с этой страницей, как и я.

Ура!

 Samarland25 сент. 2017 г., 14:31
Этот ответ и мое решение! Спасибо вам, ребята!
 MonoThreaded19 окт. 2015 г., 08:26
Один год, чтобы ответить, два года, чтобы принять :)

то вам нужно добавить ResetAbandonedTimer, как показано ниже:

jdbcInterceptors="ConnectionState;StatementFinalizer;ResetAbandonedTimer"

После установки ResetAbandonedTimer проблема была решена в моем приложении. Запрос о том, есть ли связь между перехватчиком ResetAbandonedTimer и removeAbandoned = "правда" removeAbandonedTimeout =»60"

Ваш ответ на вопрос