tomcat-jdbc 池数据源未重新连接

tomcat-jdbc pool datasource not reconnecting

我有一个 spring 启动应用程序,其数据源设置如下:

application.properties:

tomcat.jdbc.pool.url=jdbc:mysql://url/db
tomcat.jdbc.pool.username=username
tomcat.jdbc.pool.password=password
tomcat.jdbc.pool.initial-size=10
tomcat.jdbc.pool.test-on-borrow=true
tomcat.jdbc.pool.test-while-idle=true
tomcat.jdbc.pool.validation-query=SELECT 1
tomcat.jdbc.pool.driver-class-name=com.mysql.jdbc.Driver
tomcat.jdbc.pool.max_size=30
tomcat.jdbc.pool.min_size=7

DataSourceConfiguration.java

import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;


@Configuration
public class DataSourceConfiguration {

    @Value("${tomcat.jdbc.pool.max_size}")
    private int maxSize;

    @Value("${tomcat.jdbc.pool.min_size}")
    private int minSize;

    @Value("${tomcat.jdbc.pool.initial-size}")
    private int initialSize;

    @Value("${tomcat.jdbc.pool.test-on-borrow}")
    private boolean testOnBorrow;

    @Value("${tomcat.jdbc.pool.test-while-idle}")
    private boolean testWhileIdle;

    @Value("${tomcat.jdbc.pool.username}")
    private String username;

    @Value("${tomcat.jdbc.pool.password}")
    private String password;

    @Value("${tomcat.jdbc.pool.url}")
    private String url;

    @Value("${tomcat.jdbc.pool.driver-class-name}")
    private String driverClassName;

    @Value("${tomcat.jdbc.pool.validation-query}")
    private String validationQuery;

    @Bean
    @Primary
    public DataSource dataSource() {
        DataSource dataSource = new DataSource();
        dataSource.setUrl(url);
        dataSource.setPassword(password);
        dataSource.setUsername(username);
        dataSource.setDriverClassName(driverClassName);
        dataSource.setValidationQuery(validationQuery);
        dataSource.setInitialSize(initialSize);
        dataSource.setMaxIdle(maxSize);
        dataSource.setMinIdle(minSize);
        dataSource.setTestOnBorrow(testOnBorrow);
        dataSource.setTestWhileIdle(testWhileIdle);
        return dataSource;
    }
}

最后我有一个在 jdbc模板中使用此数据源的存储库:

@Repository
public class PositionRepository {

    private static JdbcTemplate jdbcTemplate;

    public PositionRepository() {}

    @Autowired
    public void setDataSource(DataSource dataSource) {
        jdbcTemplate = new JdbcTemplate(dataSource);
    }

    ...
    ...
}

我确认传递给 JdbcTemplate 构造函数的数据源确实是 org.apache.tomcat.jdbc.pool.DataSource。

然而,我偶尔会遇到以下异常:

[2015-09-29 10:44:40.098] boot - 14124  INFO [http-nio-8888-exec-5] --- XmlBeanDefinitionReader: Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
[2015-09-29 10:44:40.302] boot - 14124  INFO [http-nio-8888-exec-5] --- SQLErrorCodesFactory: SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Hana]
[2015-09-29 10:44:40.308] boot - 14124  WARN [http-nio-8888-exec-5] --- SQLErrorCodesFactory: Error while extracting database product name - falling back to empty error codes
org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:305) ~[spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:329) ~[spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.jdbc.support.SQLErrorCodesFactory.getErrorCodes(SQLErrorCodesFactory.java:214) [spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.setDataSource(SQLErrorCodeSQLExceptionTranslator.java:134) [spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.<init>(SQLErrorCodeSQLExceptionTranslator.java:97) [spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.jdbc.support.JdbcAccessor.getExceptionTranslator(JdbcAccessor.java:99) [spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:416) [spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:471) [spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:481) [spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.queryForList(JdbcTemplate.java:521) [spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.myproj.somename.repositories.PositionRepository.runQueryForList(PositionRepository.java:34) [classes/:?]
    at org.myproj.somename.repositories.PositionRepository.positionFindPaged(PositionRepository.java:52) [classes/:?]
    at org.myproj.somename.repositories.PositionRepository$$FastClassBySpringCGLIB$$ce8ed984.invoke(<generated>) [spring-core-4.1.7.RELEASE.jar:?]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) [spring-core-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717) [spring-aop-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) [spring-aop-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) [spring-tx-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653) [spring-aop-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.myproj.somename.repositories.PositionRepository$$EnhancerBySpringCGLIB$$a986c62b.positionFindPaged(<generated>) [spring-core-4.1.7.RELEASE.jar:?]
    at org.myproj.somename.controllers.api.Positions.runPositions(Positions.java:148) [classes/:?]
    at org.myproj.somename.controllers.api.Positions.runPositions(Positions.java:93) [classes/:?]
    at org.myproj.somename.controllers.api.Positions.getPositions(Positions.java:61) [classes/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[?:1.8.0]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) [spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) [spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) [tomcat-embed-core-8.0.23.jar:8.0.23]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) [spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [tomcat-

embed-core-8.0.23.jar:8.0.23]
        at ....
.....
.....
.....
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85) [spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [tomcat-embed-core-8.0.23.jar:8.0.23]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [tomcat-embed-core-8.0.23.jar:8.0.23]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) [tomcat-embed-core-8.0.23.jar:8.0.23]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.23.jar:8.0.23]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.23.jar:8.0.23]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) [tomcat-embed-core-8.0.23.jar:8.0.23]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.23.jar:8.0.23]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.23.jar:8.0.23]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) [tomcat-embed-core-8.0.23.jar:8.0.23]
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) [tomcat-embed-core-8.0.23.jar:8.0.23]
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668) [tomcat-embed-core-8.0.23.jar:8.0.23]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521) [tomcat-embed-core-8.0.23.jar:8.0.23]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478) [tomcat-embed-core-8.0.23.jar:8.0.23]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.23.jar:8.0.23]
        at java.lang.Thread.run(Thread.java:744) [?:1.8.0]
    Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:408) ~[?:1.8.0]
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:389) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.Util.getInstance(Util.java:372) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:958) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:937) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:872) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.ConnectionImpl.throwConnectionClosedException(ConnectionImpl.java:1236) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.java:1231) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.ConnectionImpl.getMetaData(ConnectionImpl.java:2938) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.ConnectionImpl.getMetaData(ConnectionImpl.java:2933) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0]
        at java.lang.reflect.Method.invoke(Method.java:483) ~[?:1.8.0]
        at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:126) ~[tomcat-jdbc-8.0.23.jar:?]
        at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108) ~[tomcat-jdbc-8.0.23.jar:?]
        at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:81) ~[tomcat-jdbc-8.0.23.jar:?]
        at com.sun.proxy.$Proxy83.getMetaData(Unknown Source) ~[?:?]
        at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:294) ~[spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        ... 103 more
    Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

    The last packet successfully received from the server was 16,234 milliseconds ago.  The last packet sent successfully to the server was 1 milliseconds ago.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:408) ~[?:1.8.0]
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:389) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1038) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3422) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3322) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3762) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2531) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2489) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1446) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at org.springframework.jdbc.core.JdbcTemplateQueryStatementCallback.doInStatement(JdbcTemplate.java:455) ~[spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:405) ~[spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        ... 97 more
    Caused by: 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:2914) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3332) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3322) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3762) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2531) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2489) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1446) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at org.springframework.jdbc.core.JdbcTemplateQueryStatementCallback.doInStatement(JdbcTemplate.java:455) ~[spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:405) ~[spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        ... 97 more
    [2015-09-29 10:44:40.344] boot - 14124 ERROR [http-nio-8888-exec-5] --- [dispatcherServlet]: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.RecoverableDataAccessException: StatementCallback; SQL [SELECT * FROM ( SELECT ticker, `type`, strike, expiration, SUM(premium) / COUNT(*) avg_premium, SUM(newquantity)*multiplier `position` FROM ( SELECT IF (ACTION = 'BOUGHT', quantity, -quantity) newquantity, e.ticker_eurex ticker, e.multiplier, tr.*  FROM trade_record tr JOIN equity e ON tr.equity_id = e.id)  a WHERE  (  `expiration` >= '2015-09-29'  ) and  true  and trade_date <= '2015-07-09'  GROUP BY ticker, TYPE, strike, expiration ORDER BY  expiration desc , strike asc , position desc  LIMIT 0,100 ) z  WHERE  true  AND position <> 0 ]; Communications link failure

    The last packet successfully received from the server was 16,234 milliseconds ago.  The last packet sent successfully to the server was 1 milliseconds ago.; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

    The last packet successfully received from the server was 16,234 milliseconds ago.  The last packet sent successfully to the server was 1 milliseconds ago.] 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:2914) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3332) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3322) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3762) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2531) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2489) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1446) ~[mysql-connector-java-5.1.35.jar:5.1.35]
        at org.springframework.jdbc.core.JdbcTemplateQueryStatementCallback.doInStatement(JdbcTemplate.java:455) ~[spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:405) ~[spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:471) ~[spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:481) ~[spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate.queryForList(JdbcTemplate.java:521) ~[spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.myproj.somename.repositories.PositionRepository.runQueryForList(PositionRepository.java:34) ~[classes/:?]
        at org.myproj.somename.repositories.PositionRepository.positionFindPaged(PositionRepository.java:52) ~[classes/:?]
        at org.myproj.somename.repositories.PositionRepository$$FastClassBySpringCGLIB$$ce8ed984.invoke(<generated>) ~[spring-core-4.1.7.RELEASE.jar:?]
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717) ~[spring-aop-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653) ~[spring-aop-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.myproj.somename.repositories.PositionRepository$$EnhancerBySpringCGLIB$$a986c62b.positionFindPaged(<generated>) ~[spring-core-4.1.7.RELEASE.jar:?]
        at org.myproj.somename.controllers.api.Positions.runPositions(Positions.java:148) ~[classes/:?]
        at org.myproj.somename.controllers.api.Positions.runPositions(Positions.java:93) ~[classes/:?]
        at org.myproj.somename.controllers.api.Positions.getPositions(Positions.java:61) ~[classes/:?]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0]
        at java.lang.reflect.Method.invoke(Method.java:483) ~[?:1.8.0]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
    .....
    .....
    ....


    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) [tomcat-embed-core-8.0.23.jar:8.0.23]
                at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.23.jar:8.0.23]
                at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.23.jar:8.0.23]
                at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) [tomcat-embed-core-8.0.23.jar:8.0.23]
                at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) [tomcat-embed-core-8.0.23.jar:8.0.23]
                at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668) [tomcat-embed-core-8.0.23.jar:8.0.23]
                at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521) [tomcat-embed-core-8.0.23.jar:8.0.23]
                at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478) [tomcat-embed-core-8.0.23.jar:8.0.23]
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0]
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0]
                at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.23.jar:8.0.23]
                at java.lang.Thread.run(Thread.java:744) [?:1.8.0]

有人能告诉我我做错了什么吗?难道不是使用连接池来避免此类问题的全部意义所在吗?我能以某种方式告诉 tomcat-jdbc 我不想要异常,除非它尝试重新连接 X 次吗?除此之外,setTestOnBorrow 和 setTestOnIdle 都设置为 true。

有人知道发生了什么事吗?我的设置有问题吗?

提前致谢!

P.S.

我在一处截断了异常以适应 SO 的最大字符限制。

长话短说,我最终放弃了 jdbc-pool,因为事实证明这绝对是浪费时间。我决定用我的 Spring Boot 后端给 HikariCP 一个机会,我非常高兴。在超级基本设置后,它开始自动优雅地处理断开连接问题。

如果你是 运行 Spring 启动你只需要将它添加到你的 pom.xml

<!-- HikariCP DB Connection Pooling -->
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>2.4.1</version>
</dependency>

然后你只需要相应地设置 HikariCP 属性。这是我的设置,我遇到了 0 个问题

# hikariCP
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.datasource.url=jdbc:mysql://localhost/some_db_name?useUnicode=true&characterEncoding=utf8&dumpQueriesOnException=true
spring.datasource.username=<your_username_here>
spring.datasource.password=<your_password_here>
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.pool-name=SpringBootHikariCP
spring.datasource.maximum-pool-size=8
spring.datasource.minimum-idle=5
spring.datasource.max-lifetime=2000000
spring.datasource.connection-timeout=30000
spring.datasource.idle-timeout=30000
spring.datasource.pool-prepared-statements=true
spring.datasource.max-open-prepared-statements=250
spring.datasource.validation-query=SELECT 1
spring.datasource.pool-prepared-statements=true
spring.datasource.pool-prepared-statements-cache-size=250
spring.datasource.pool-prepared-statements-cache-sql-limit=2048
spring.datasource.user-server-prepared-statements=true

最后这是使用上述属性的相应数据源配置

@EnableTransactionManagement
@Configuration
public class DataSourceConfiguration {

    // HikariCP

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;

    @Value("${spring.datasource.pool-name}")
    private String poolName;

    @Value("${spring.datasource.connection-timeout}")
    private int connectionTimeout;

    @Value("${spring.datasource.max-lifetime}")
    private int maxLifetime;

    @Value("${spring.datasource.maximum-pool-size}")
    private int maximumPoolSize;

    @Value("${spring.datasource.minimum-idle}")
    private int minimumIdle;

    @Value("${spring.datasource.idle-timeout}")
    private int idleTimeout;

    @Value("${spring.datasource.validation-query}")
    private String validationQuery;

    @Value("${spring.datasource.pool-prepared-statements}")
    private String cachePrepStmts;

    @Value("${spring.datasource.pool-prepared-statements-cache-size}")
    private String prepStmtCacheSize;

    @Value("${spring.datasource.pool-prepared-statements-cache-sql-limit}")
    private String prepStmtCacheSqlLimit;

    @Value("${spring.datasource.user-server-prepared-statements}")
    private String useServerPrepStmts;

    @Bean
    public DataSource primaryDataSource() {

        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setDriverClassName(driverClassName);
        hikariConfig.setJdbcUrl(url); 
        hikariConfig.setUsername(username);
        hikariConfig.setPassword(password);
        hikariConfig.setMaximumPoolSize(maximumPoolSize);
        hikariConfig.setMinimumIdle(minimumIdle);
        hikariConfig.setConnectionTimeout(connectionTimeout);
        hikariConfig.setIdleTimeout(idleTimeout);
        hikariConfig.setConnectionTestQuery(validationQuery);
        hikariConfig.setPoolName("springHikariCP");

        hikariConfig.addDataSourceProperty("dataSource.cachePrepStmts", cachePrepStmts);
        hikariConfig.addDataSourceProperty("dataSource.prepStmtCacheSize", prepStmtCacheSize);
        hikariConfig.addDataSourceProperty("dataSource.prepStmtCacheSqlLimit", prepStmtCacheSqlLimit);
        hikariConfig.addDataSourceProperty("dataSource.useServerPrepStmts", useServerPrepStmts);

        HikariDataSource ds = new HikariDataSource(hikariConfig);
        return ds;
    }

}

这就是我解决问题的原因。