什么原因导致 MariaDB 服务器出现 SpringJDBC 套接字写入错误?
What cause SpringJDBC socket write error with MariaDB server?
我的 tomcat 应用程序服务器有一个 Spring JDBC 模板服务来连接到本地 MariaDB 数据库。
我正在使用 Spring-Jdbc 库版本 4.2.3,Mariadb-java-client 库版本 2.0.1 和 MariaDB 版本 10.1.18。
有时,我可以随意地说,我在应用程序服务器和数据库之间进行查询操作时遇到此错误:
java.net.SocketException:软件导致连接中止:套接字写入错误
这是完整的堆栈
org.springframework.dao.DataAccessResourceFailureException: PreparedStatementCallback; SQL [select exists (select 1 from smartcard where status>=?)]; (conn:13) Could not send query: Software caused connection abort: socket write error; nested exception is java.sql.SQLNonTransientConnectionException: (conn:13) Could not send query: Software caused connection abort: socket write error
at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:79) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:645) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:680) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:722) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:790) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:814) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at com.mypackage.dao.SmartcardDao.hasPronte(SmartcardDao.java:83) ~[classes/:?]
at com.mypackage.smartcard.SmartcardService.isReady(SmartcardService.java:215) ~[classes/:?]
at com.mypackage.check.CheckService.isReady(CheckService.java:362) ~[classes/:?]
at com.mypackage.check.CheckService.getPing(CheckService.java:398) ~[classes/:?]
at com.mypackage.check.CheckService.getPingAuth(CheckService.java:408) ~[classes/:?]
at com.mypackage.remote.update.UpdateService.sendPing(UpdateService.java:48) ~[classes/:?]
at com.mypackage.check.CheckService.run(CheckService.java:170) [classes/:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_131]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:1.8.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_131]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131]
Caused by: java.sql.SQLNonTransientConnectionException: (conn:13) Could not send query: Software caused connection abort: socket write error
at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.get(ExceptionMapper.java:156) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.getException(ExceptionMapper.java:118) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbStatement.executeExceptionEpilogue(MariaDbStatement.java:229) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.executeInternal(MariaDbPreparedStatementClient.java:208) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.execute(MariaDbPreparedStatementClient.java:147) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.executeQuery(MariaDbPreparedStatementClient.java:161) ~[mariadb-java-client-2.0.1.jar:?]
at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_131]
at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114) ~[tomcat-jdbc.jar:?]
at com.sun.proxy.$Proxy47.executeQuery(Unknown Source) ~[?:?]
at org.springframework.jdbc.core.JdbcTemplate.doInPreparedStatement(JdbcTemplate.java:688) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:629) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
... 19 more
Caused by: java.sql.SQLException: Could not send query: Software caused connection abort: socket write error
at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.handleIoException(AbstractQueryProtocol.java:1428) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.executeQuery(AbstractQueryProtocol.java:217) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.executeInternal(MariaDbPreparedStatementClient.java:203) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.execute(MariaDbPreparedStatementClient.java:147) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.executeQuery(MariaDbPreparedStatementClient.java:161) ~[mariadb-java-client-2.0.1.jar:?]
at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_131]
at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114) ~[tomcat-jdbc.jar:?]
at com.sun.proxy.$Proxy47.executeQuery(Unknown Source) ~[?:?]
at org.springframework.jdbc.core.JdbcTemplate.doInPreparedStatement(JdbcTemplate.java:688) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:629) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
... 19 more
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method) ~[?:1.8.0_131]
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111) ~[?:1.8.0_131]
at java.net.SocketOutputStream.write(SocketOutputStream.java:155) ~[?:1.8.0_131]
at org.mariadb.jdbc.internal.io.output.StandardPacketOutputStream.flushBuffer(StandardPacketOutputStream.java:101) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.internal.io.output.AbstractPacketOutputStream.flush(AbstractPacketOutputStream.java:157) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.executeQuery(AbstractQueryProtocol.java:210) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.executeInternal(MariaDbPreparedStatementClient.java:203) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.execute(MariaDbPreparedStatementClient.java:147) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.executeQuery(MariaDbPreparedStatementClient.java:161) ~[mariadb-java-client-2.0.1.jar:?]
at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_131]
at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114) ~[tomcat-jdbc.jar:?]
at com.sun.proxy.$Proxy47.executeQuery(Unknown Source) ~[?:?]
at org.springframework.jdbc.core.JdbcTemplate.doInPreparedStatement(JdbcTemplate.java:688) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:629) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
... 19 more
这是DataSource对象的属性:
org.apache.tomcat.jdbc.pool.DataSource@10a3e2b{ConnectionPool[
defaultAutoCommit=null;
defaultReadOnly=null;
defaultTransactionIsolation=-1;
defaultCatalog=null;
driverClassName=org.mariadb.jdbc.Driver;
maxActive=10;
maxIdle=5;
minIdle=2;
initialSize=5;
maxWait=30000;
testOnBorrow=false;
testOnReturn=false;
timeBetweenEvictionRunsMillis=5000;
numTestsPerEvictionRun=0;
minEvictableIdleTimeMillis=60000;
testWhileIdle=false;
testOnConnect=false;
password=********;
url=jdbc:mariadb://localhost/mydb?autoReconnect=true&useSSL=false;
username=myuser;
validationQuery=null;
validationQueryTimeout=-1;
validatorClassName=null;
validationInterval=3000;
accessToUnderlyingConnectionAllowed=true;
removeAbandoned=true;
removeAbandonedTimeout=60;
logAbandoned=true;
connectionProperties=null;
initSQL=null;
jdbcInterceptors=null;
jmxEnabled=true;
fairQueue=true;
useEquals=true;
abandonWhenPercentageFull=0;
maxAge=0;
useLock=false;
dataSource=null;
dataSourceJNDI=null;
suspectTimeout=0;
alternateUsernameAllowed=false;
commitOnReturn=false;
rollbackOnReturn=false;
useDisposableConnectionFacade=true;
logValidationErrors=false;
propagateInterruptState=false;
ignoreExceptionOnPreLoad=false;
}
考虑到数据库机器和应用机器是一样的,这是连接字符串:
jdbc:mariadb://localhost/mydb?autoReconnect=true&useSSL=false
可能是什么原因?
我在 windows (Win 10) 和 linux (Ubuntu 服务器 16.04.2 LTS) 机器上都遇到过这个问题。
这闻起来像是池中的陈旧连接,已被服务器关闭。不可能肯定地说,因为这只是一个可能有许多根本原因的症状。然而,运行 是一个常见问题。
在jdbcurl上启用了炫目的"autoReconnect"属性,听起来应该可以解决所有问题吧? autoReconnect 的原始 MySQL 描述是
If enabled the driver will throw an exception for a queries issued on
a stale or dead connection, which belong to the current transaction,
but will attempt reconnect before the next query issued on the
connection in a new transaction
(source)
强调我的。所以 属性 可能不会按照您的想法去做。 existing Stack Overflow question 进一步支持了这一点。不过,我不知道 MariaDB 中是否有任何更改,我真的不能这么快找到任何关于它的具体文档。
防止池中过时连接的最佳方法是让连接池为您做这件事,您可以为此定义数据源属性testOnBorrow、testOnConnect、testOnIdle,如本 existing answer 所示。 testOnBorrow 可能就足够了。我会引用它以防万一 link 碰巧中断:
spring.datasource.tomcat.testOnBorrow=true
spring.datasource.tomcat.validationQuery=SELECT 1
假定 Spring Boot 的版本较新,不难将其转换为您正在使用的 Spring。
我的 tomcat 应用程序服务器有一个 Spring JDBC 模板服务来连接到本地 MariaDB 数据库。
我正在使用 Spring-Jdbc 库版本 4.2.3,Mariadb-java-client 库版本 2.0.1 和 MariaDB 版本 10.1.18。
有时,我可以随意地说,我在应用程序服务器和数据库之间进行查询操作时遇到此错误:
java.net.SocketException:软件导致连接中止:套接字写入错误
这是完整的堆栈
org.springframework.dao.DataAccessResourceFailureException: PreparedStatementCallback; SQL [select exists (select 1 from smartcard where status>=?)]; (conn:13) Could not send query: Software caused connection abort: socket write error; nested exception is java.sql.SQLNonTransientConnectionException: (conn:13) Could not send query: Software caused connection abort: socket write error
at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:79) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:645) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:680) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:722) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:790) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:814) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at com.mypackage.dao.SmartcardDao.hasPronte(SmartcardDao.java:83) ~[classes/:?]
at com.mypackage.smartcard.SmartcardService.isReady(SmartcardService.java:215) ~[classes/:?]
at com.mypackage.check.CheckService.isReady(CheckService.java:362) ~[classes/:?]
at com.mypackage.check.CheckService.getPing(CheckService.java:398) ~[classes/:?]
at com.mypackage.check.CheckService.getPingAuth(CheckService.java:408) ~[classes/:?]
at com.mypackage.remote.update.UpdateService.sendPing(UpdateService.java:48) ~[classes/:?]
at com.mypackage.check.CheckService.run(CheckService.java:170) [classes/:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_131]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:1.8.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_131]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131]
Caused by: java.sql.SQLNonTransientConnectionException: (conn:13) Could not send query: Software caused connection abort: socket write error
at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.get(ExceptionMapper.java:156) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.getException(ExceptionMapper.java:118) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbStatement.executeExceptionEpilogue(MariaDbStatement.java:229) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.executeInternal(MariaDbPreparedStatementClient.java:208) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.execute(MariaDbPreparedStatementClient.java:147) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.executeQuery(MariaDbPreparedStatementClient.java:161) ~[mariadb-java-client-2.0.1.jar:?]
at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_131]
at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114) ~[tomcat-jdbc.jar:?]
at com.sun.proxy.$Proxy47.executeQuery(Unknown Source) ~[?:?]
at org.springframework.jdbc.core.JdbcTemplate.doInPreparedStatement(JdbcTemplate.java:688) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:629) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
... 19 more
Caused by: java.sql.SQLException: Could not send query: Software caused connection abort: socket write error
at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.handleIoException(AbstractQueryProtocol.java:1428) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.executeQuery(AbstractQueryProtocol.java:217) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.executeInternal(MariaDbPreparedStatementClient.java:203) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.execute(MariaDbPreparedStatementClient.java:147) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.executeQuery(MariaDbPreparedStatementClient.java:161) ~[mariadb-java-client-2.0.1.jar:?]
at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_131]
at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114) ~[tomcat-jdbc.jar:?]
at com.sun.proxy.$Proxy47.executeQuery(Unknown Source) ~[?:?]
at org.springframework.jdbc.core.JdbcTemplate.doInPreparedStatement(JdbcTemplate.java:688) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:629) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
... 19 more
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method) ~[?:1.8.0_131]
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111) ~[?:1.8.0_131]
at java.net.SocketOutputStream.write(SocketOutputStream.java:155) ~[?:1.8.0_131]
at org.mariadb.jdbc.internal.io.output.StandardPacketOutputStream.flushBuffer(StandardPacketOutputStream.java:101) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.internal.io.output.AbstractPacketOutputStream.flush(AbstractPacketOutputStream.java:157) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.executeQuery(AbstractQueryProtocol.java:210) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.executeInternal(MariaDbPreparedStatementClient.java:203) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.execute(MariaDbPreparedStatementClient.java:147) ~[mariadb-java-client-2.0.1.jar:?]
at org.mariadb.jdbc.MariaDbPreparedStatementClient.executeQuery(MariaDbPreparedStatementClient.java:161) ~[mariadb-java-client-2.0.1.jar:?]
at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_131]
at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114) ~[tomcat-jdbc.jar:?]
at com.sun.proxy.$Proxy47.executeQuery(Unknown Source) ~[?:?]
at org.springframework.jdbc.core.JdbcTemplate.doInPreparedStatement(JdbcTemplate.java:688) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:629) ~[spring-jdbc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
... 19 more
这是DataSource对象的属性:
org.apache.tomcat.jdbc.pool.DataSource@10a3e2b{ConnectionPool[
defaultAutoCommit=null;
defaultReadOnly=null;
defaultTransactionIsolation=-1;
defaultCatalog=null;
driverClassName=org.mariadb.jdbc.Driver;
maxActive=10;
maxIdle=5;
minIdle=2;
initialSize=5;
maxWait=30000;
testOnBorrow=false;
testOnReturn=false;
timeBetweenEvictionRunsMillis=5000;
numTestsPerEvictionRun=0;
minEvictableIdleTimeMillis=60000;
testWhileIdle=false;
testOnConnect=false;
password=********;
url=jdbc:mariadb://localhost/mydb?autoReconnect=true&useSSL=false;
username=myuser;
validationQuery=null;
validationQueryTimeout=-1;
validatorClassName=null;
validationInterval=3000;
accessToUnderlyingConnectionAllowed=true;
removeAbandoned=true;
removeAbandonedTimeout=60;
logAbandoned=true;
connectionProperties=null;
initSQL=null;
jdbcInterceptors=null;
jmxEnabled=true;
fairQueue=true;
useEquals=true;
abandonWhenPercentageFull=0;
maxAge=0;
useLock=false;
dataSource=null;
dataSourceJNDI=null;
suspectTimeout=0;
alternateUsernameAllowed=false;
commitOnReturn=false;
rollbackOnReturn=false;
useDisposableConnectionFacade=true;
logValidationErrors=false;
propagateInterruptState=false;
ignoreExceptionOnPreLoad=false;
}
考虑到数据库机器和应用机器是一样的,这是连接字符串:
jdbc:mariadb://localhost/mydb?autoReconnect=true&useSSL=false
可能是什么原因? 我在 windows (Win 10) 和 linux (Ubuntu 服务器 16.04.2 LTS) 机器上都遇到过这个问题。
这闻起来像是池中的陈旧连接,已被服务器关闭。不可能肯定地说,因为这只是一个可能有许多根本原因的症状。然而,运行 是一个常见问题。
在jdbcurl上启用了炫目的"autoReconnect"属性,听起来应该可以解决所有问题吧? autoReconnect 的原始 MySQL 描述是
If enabled the driver will throw an exception for a queries issued on a stale or dead connection, which belong to the current transaction, but will attempt reconnect before the next query issued on the connection in a new transaction
(source)
强调我的。所以 属性 可能不会按照您的想法去做。 existing Stack Overflow question 进一步支持了这一点。不过,我不知道 MariaDB 中是否有任何更改,我真的不能这么快找到任何关于它的具体文档。
防止池中过时连接的最佳方法是让连接池为您做这件事,您可以为此定义数据源属性testOnBorrow、testOnConnect、testOnIdle,如本 existing answer 所示。 testOnBorrow 可能就足够了。我会引用它以防万一 link 碰巧中断:
spring.datasource.tomcat.testOnBorrow=true
spring.datasource.tomcat.validationQuery=SELECT 1
假定 Spring Boot 的版本较新,不难将其转换为您正在使用的 Spring。