Воспроизведите com.mysql.jdbc.exceptions.jdbc4.CommunicationsException с настройками Spring, hibernate и C3P0. - PullRequest
14 голосов
/ 03 октября 2009

Я получил эту ошибку из производственного кода:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Последний пакет успешно получен с сервера было 36940 секунд назад. Последний пакет успешно отправлен на сервер было 36940 секунд назад, который длиннее сервера настроенное значение 'wait_timeout'. Вы должны рассмотреть либо истекает и / или проверка правильности подключения перед использованием в вашем приложении, увеличение настроенного сервера значения времени ожидания клиента или использования свойство соединения Connector / J 'autoReconnect = true', чтобы избежать этого проблема.

А сейчас я пытаюсь воспроизвести проблему локально и исправить ее. Я устанавливаю контекст весны следующим образом:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close" p:driverClass="com.mysql.jdbc.Driver"
    p:jdbcUrl="jdbc:mysql://localhost:3306/test?userUnicode=yes&amp;characterEncoding=UTF-8&amp"
    p:idleConnectionTestPeriod="120" p:initialPoolSize="1" p:maxIdleTime="1800"
    p:maxPoolSize="1" p:minPoolSize="1" p:checkoutTimeout="1000"

/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="hibernateProperties">
        <value>
            hibernate.connection.provider_class = org.hibernate.connection.C3P0ConnectionProvider
            hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
            hibernate.default_schema=platform_server_original
            hibernate.show_sql=false
        </value>
    </property>
    <property name="mappingResources">
        <list>
            <value>sometables.hbm.xml</value>
        </list>
    </property>
</bean>

Затем я установил свой mysql wait_timeout на 10 секунд, затем запустил мой тест, который в основном открывает соединение, выполняет запрос, закрывает его, чтобы он вернулся в пул, затем спит поток в течение 15 секунд, а затем открывает снова соединение и повторите запрос, чтобы оно разорвалось. Однако я получил похожую ошибку только:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Отказ линии связи

Последний отправленный на сервер пакет был 16 мс назад.

Итак, мне интересно, являются ли эти две ошибки одинаковыми или они разные? Я провел некоторые исследования, и кажется, что обе ошибки сводились к одному и тому же решению: использование свойства "testConnectionOnCheckout = true". Однако, согласно документу c3p0, это очень дорогая проверка. Рекомендуется использовать «idleConnectionTestPeriod», но я уже установил это значение на 120 секунд. Какое значение я должен использовать, чтобы он мог правильно проверить соединение в режиме ожидания?

Так что я в основном спрашиваю две вещи: 1. как воспроизвести ошибку, полученную в рабочем коде? 2. как мне это исправить?

Спасибо!

Ответы [ 3 ]

3 голосов
/ 12 октября 2009

У меня были похожие проблемы с MySQL и пулом соединений. Проблема заключается в том, что вы сообщаете пулу соединений, что время простоя составляет 30 минут, но база данных прерывает соединение через 10 секунд. Поскольку период проверки простоя соединения составляет 120 секунд, для пула остается чуть меньше 110 секунд, чтобы пул использовал разорванное соединение!

Я бы использовал следующие настройки для производства:

MySQL:
wait_timeout=75
C3P0:
maxIdleTime=60
idleConnectionTestPeriod=55
0 голосов
/ 07 октября 2009

Чтобы воспроизвести вашу ошибку, задайте для своего тайм-аута подключения в свойствах MySQL очень низкое значение, то есть 2 мс, и выполните запрос, для которого известно, что он имеет большое время обработки. Вы можете установить свойство timeout либо в строке подключения MySQL, либо через свойство, если вы используете файлы свойств для настройки соединения JDBC. Вы можете найти Javadocs на вашем конкретном соединении jaxax.sql.DataSource и документацию MySQL, чтобы узнать, как это сделать.

0 голосов
/ 06 октября 2009

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

Предлагаем добавить номера версий MySQL / Spring / Hibernate / C3PO / JDBC к вашему вопросу на случай, если там есть известная проблема.

Распространенное сообщение об ошибке со многими возможными основными причинами. Некоторые выводы для вас:

  1. Ошибка производства может указывать что ваше приложение не освобождение соединения обратно к пул, когда сделано с ним, предотвращая c3p0 от проверки этого. (C3p0 холостые проверки могут применяться только к непроверенные соединения.)

  2. Убедитесь, что c3p0 действительно работает (вы можете использовать «ваниль» соединения если нет). В вашем тесте если вы установите (например) MySql wait_timeout = 10, поток приложения сон = 35, и idleConnectionTestPeriod = 30, если пул работает, исключение должен уйти.

  3. На счет холостых проверок: рассмотреть вопрос об использовании по умолчанию getTables () - может быть установлен ПредпочиталTestQuery чем-то дешевым (-er) 'SELECT 1', может быть для MySQL?

...