Java 空闲时间后连接池中的Tomcat Mysql连接超时

Java 空闲时间后连接池中的Tomcat Mysql连接超时,java,mysql,tomcat,database-connection,connection-pooling,Java,Mysql,Tomcat,Database Connection,Connection Pooling,我目前正在使用tomcat 6和MySQL 5.1.56。 它使用Mysql Connector-j获取数据库连接并使用它们。 我已根据此链接设置了连接池 只要我使用它,一切都很好 如果我让它闲置几个小时,那么我就无法执行任何查询。 我得到以下例外 com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: **No operations allowed after connection closed.** jav

我目前正在使用tomcat 6和MySQL 5.1.56。 它使用Mysql Connector-j获取数据库连接并使用它们。 我已根据此链接设置了连接池

只要我使用它,一切都很好

如果我让它闲置几个小时,那么我就无法执行任何查询。 我得到以下例外

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)
我看到堆栈上的另一个人问了同样的问题,但没有回答。

我在这里找到了一个解决方案,但我不能使用它,因为它指示我使用另一个我没有权限这样做的第三方应用程序

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日志中找不到任何内容。

您不应该让任何连接在几个小时内保持打开状态

您应该有一个持久层,该层从池中获取连接,执行操作,提交或回滚,并关闭连接以在尽可能小的范围内将其返回到池中。如果您不限制每个会话只能有一个连接,那么您的应用程序将具有更大的可伸缩性。您的应用程序将具有足够的响应能力,因为池将在您的所有请求中分摊打开每个连接的成本


有些池的配置允许您在将连接从池中释放出来之前检查连接,并在连接过时时提供新的连接。查看如何使用池/应用程序服务器执行此操作。

将以下属性添加到资源标签中

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

tomcat将在从连接池借用连接时验证连接。

我有一段时间使用此配置,但我连接到Oracle数据库。我觉得30秒对于validationInterval和timeBetweenEvictionRunsMillis来说太短了,但这只意味着测试将更频繁地运行

除此之外,我还将numTestsPervictionRun设置为“-1”,这意味着它将测试所有空闲连接。现在,该文件明确指出该属性未被使用,因此无法判断它是否有帮助。你得试试看

numTestsPerEvictionRun="-1"
numTestsPervictionRun=“-1”是,这就是我正在做的。连接返回池后,问题就会出现。如果我让应用程序闲置几个小时,那么池中的连接将变得不可用。这就是我试图解决的问题。@kensenjohn:你是如何解决这个问题的?除了autoreconnect之外,我使用相同的配置。它可以工作,但是如果我使用SSL,我会得到相同的错误。你会注意到在我的问题中,我已经设置了所有这些参数,但我仍然有问题。在用尽所有这些选项之后,我写了这个问题。我会尝试一下,但是正如你提到的,它确实指定tomcat不使用这个参数。谢谢,你是怎么解决的?