Как переподключить базу данных, если соединение закрыто весной jpa?
Я использую spring-boot, spring-jpa, mysql в своем веб-приложении. Когда мое приложение работает в течение нескольких часов, я всегда получаю следующие исключения:
2016-07-30 21:27:12.434 ERROR 13553 --- [http-nio-8090-exec-8] o.h.engine.jdbc.spi.SqlExceptionHelper : No operations allowed after connection closed.
2016-07-30 21:27:12.434 WARN 13553 --- [http-nio-8090-exec-5] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 08003
2016-07-30 21:27:12.434 ERROR 13553 --- [http-nio-8090-exec-5] o.h.engine.jdbc.spi.SqlExceptionHelper : No operations allowed after connection closed.
2016-07-30 21:27:12.438 ERROR 13553 --- [http-nio-8090-exec-8] [.[.[.[.c.c.Go2NurseJerseyConfiguration] : Servlet.service() for servlet [com.cooltoo.config.Go2NurseJerseyConfiguration] in context with path [] threw exception [org.springframework.dao.DataAccessResourceFailureException: could not prepare statement; nested exception is org.hibernate.exception.JDBCConnectionException: could not prepare statement] with root cause
java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3119) ~[mysql-connector-java-5.1.25.jar!/:na]
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3570) ~[mysql-connector-java-5.1.25.jar!/:na]
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3559) ~[mysql-connector-java-5.1.25.jar!/:na]
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4110) ~[mysql-connector-java-5.1.25.jar!/:na]
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570) ~[mysql-connector-java-5.1.25.jar!/:na]
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731) ~[mysql-connector-java-5.1.25.jar!/:na]
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815) ~[mysql-connector-java-5.1.25.jar!/:na]
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155) ~[mysql-connector-java-5.1.25.jar!/:na]
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2322) ~[mysql-connector-java-5.1.25.jar!/:na]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:82) ~[hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
Я проверил, что база данных работает хорошо. Я должен перезапустить мое приложение весенней загрузки, когда это произошло. Как я могу проверить, в чем проблема? Почему соединение с базой данных было закрыто? Если это произошло, могу ли я повторно подключить базу данных? Ниже мое приложение. Свойства:
spring.datasource.url=jdbc:mysql://192.168.99.100:3306/test?characterEncoding=utf8
spring.datasource.username=admin
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.max-active=150
1 ответ
Это похоже на общую ошибку с MySQL.
1) Добавьте это в ваш application.properties и посмотрите, как это будет:
spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1
testOnBorrow подробно описан в весеннем документе и этом другом вопросе о переполнении стека. Я, однако, не могу найти ссылку на validationQuery в документе Spring, но, похоже, это помогает.
2) Или вы можете использовать testWhileIdle, как предложено здесь http://christoph-burmeister.eu/?p=2849
Он предлагает добавить это в ваше application.properties:
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
Это решение также упоминается в другом вопросе stackru, оно просто не было принято, но, похоже, является решением для некоторых.
3) В этом случае они также добавили timeBetweenEvictionRunsMillis:
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
spring.datasource.timeBetweenEvictionRunsMillis = 3600000
РЕДАКТИРОВАТЬ: еще один вопрос stackru, который охватывает это (с очень полным ответом)