经过一会儿(几个小时)后,我们从DBCP获得了CommunicationsException。错误消息(位于“异常”中)在此问题的末尾-但我看不到任何配置文件中定义的wait_timeout。 (我们应该看哪里?在tomcat/conf目录之外的某个地方?)。

其次,如异常所建议,将“Connector/J连接属性'autoReconnect = true'”放在哪里?这是在Tomcat中设置的conf/context.xml文件中的资源定义:

<Resource name="jdbc/TomcatResourceName" auth="Container" type="javax.sql.DataSource"
           maxActive="100" maxIdle="30" maxWait="10000"
           removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true"
           username="xxxx" password="yyyy"
           driverClassName="com.mysql.jdbc.Driver"
           url="jdbc:mysql://127.0.0.1:3306/dbname?autoReconnect=true"/>

第三,为什么JVM一直等到对executeQuery()的调用引发异常?如果连接超时,则getConnection方法应该抛出Exception,不是吗?这是我正在谈论的源代码部分:
        try {
                conn = getConnection (true);
                stmt = conn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
                                                ResultSet.CONCUR_READ_ONLY);
                rset = stmt.executeQuery (bQuery);
                while (rset.next()) {
                     ....

最后,这是堆栈跟踪的第一行...
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 84,160,724 milliseconds ago.  The last packet sent successfully to the server was 84,160,848 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3291)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1938)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2107)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2642)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2571)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1451)
at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208)

这些就是我们中的一些人认为“忘记dbcp的原因,它可能过于依赖IDE配置和高级功能,以至于DriverManager.getConnection(...)可能更可靠”。对此有何评论?谢谢您的见解,-MS

最佳答案

由于DBCP使即将返回的mysql连接保持打开状态以应对即将出现的连接请求,因此它们成为MySQL Server timeout的受害者。

DBCP具有许多可以提供帮助的功能(可以从Tomcat 5.5 IIRC开始使用)。

validationQuery="SELECT 1"
testOnBorrow="true"

验证可确保连接有效,然后再将其返回到执行“借阅”方法的Web应用程序。该标志当然会启用此功能。

如果超时(我相信是8个小时)已经过去并且连接已终止,则将测试新的连接(如果不再存在,则创建该连接)并将其提供给webapp。

其他可能的方法:
  • 在资源设置中使用testWhileIdle="true" DBCP还可以在检测到有效请求之前检查空闲连接。
  • 使用'connectionProperties'加强您的MySQL连接(例如autoReconnect/autoReconnectForPools=true)
  • 09-27 15:04