Соединения Tomcat-Mysql в пуле соединений истекают после простоя - PullRequest
3 голосов
/ 17 марта 2012

В настоящее время я использую Tomcat 6 и MySQL 5.1.56. Он использует Mysql Connector-j для получения соединений с БД и их использования. Я настроил пул соединений по этой ссылке.

http://people.apache.org/~fhanik/tomcat/jdbc-pool.html

Все работает нормально, пока я его использую.

Если я оставлю его без дела на несколько часов, я не смогу выполнить никаких запросов. Я получаю следующее исключение.

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: **No operations allowed after connection closed.**
java.lang.RuntimeException: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.

Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: **Communications link failure**

The last packet successfully received from the server was 31,858,914 milliseconds ago.  The last packet sent successfully to the server was 11 milliseconds ago.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3090)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2979)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3520)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1990)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2151)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2625)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2119)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2281)

Я видел, как другой человек в стеке переполнял тот же вопрос, но без ответа. Тайм-аут соединений с базой данных (пул соединений на Tomcat)

Я нашел решение здесь, но не могу его использовать, так как он указывает мне использовать другое стороннее приложение, на которое у меня нет разрешения.

https://groups.google.com/group/ctjug-forum/browse_thread/thread/c326d3595d0c91af

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

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

Это мои текущие настройки в conext.xml

 <Resource name="jdbc/appdb"  auth="Container"
              type="javax.sql.DataSource" 
              username="**********" 
              password="**********" 
              driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost:3306/appdb?autoReconnect=true"
              maxActive="15"  maxIdle="3"
                testWhileIdle="true"
              testOnBorrow="true"
              testOnReturn="false"
              validationQuery="SELECT 1"
              validationInterval="30000"
              timeBetweenEvictionRunsMillis="30000"/>

Какое наилучшее практическое решение в этом случае?

Я не смог ничего найти в логах mysql.

Ответы [ 3 ]

2 голосов
/ 17 марта 2012

Добавьте следующие атрибуты в тег ресурса

validationQuery="select 1"
testOnBorrow="true"
validationInterval="YOUR_VALIDATON_INTERVAL"

, и tomcat проверит соединение при заимствовании его из пула соединений.

2 голосов
/ 17 марта 2012

Не следует оставлять соединение открытым в течение нескольких часов.

У вас должен быть уровень постоянства, который получает соединение из пула, выполняет операцию (операции), фиксирует или откатывает и закрывает соединение, чтобы вернуть его обратно в пул в наименьшей возможной области видимости. Ваше приложение будет гораздо более масштабируемым, если вы не ограничите себя одним соединением за сеанс. Ваше приложение будет достаточно отзывчивым, поскольку пул будет амортизировать стоимость открытия каждого соединения по всем вашим запросам.

Некоторые пулы имеют конфигурацию, которая позволяет вам проверять соединение, прежде чем выпустить его из пула, и предоставить новое, если оно устарело. Посмотрите, как это сделать с вашим сервером пулов / приложений.

1 голос
/ 17 марта 2012

Эта конфигурация работает некоторое время, но я подключаюсь к базе данных Oracle.Я чувствую, что 30 секунд слишком мало для validationInterval и timeBetweenEvictionRunsMillis, но это только означает, что тесты будут выполняться чаще.

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

numTestsPerEvictionRun="-1"
...