java - 使用 DBCP 配置 Tomcat

标签 java mysql jdbc apache-commons-dbcp

在等待一段时间(几个小时)后,我们收到一个 CommunicationsException(来自 DBCP)。错误消息(在异常中)在这个问题的末尾 - 但我没有看到任何配置文件中定义的 wait_timeout 。 (我们应该看哪里?在 tomcat/conf 目录之外的某个地方?)。

其次,如 Exception 所建议的,将“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 方法应该抛出异常,不是吗?这是我正在谈论的源代码部分:

        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。

其他可能的方法:

  1. 在您的资源设置中使用 testWhileIdle="true" DBCP 也可以在检测到有效请求之前检查空闲连接。

  2. 使用“connectionProperties”加强您的 MySQL 连接(例如 autoReconnect/autoReconnectForPools=true)

关于java - 使用 DBCP 配置 Tomcat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4950396/

相关文章:

java - 正则表达式最后一次出现,后面仍然有关键字

mysql - 在 SQL 中以分钟为单位动态生成时间间隔之间的时间序列

mysql - java.sql.ResultSet.next() 说明

java - 如何为 JDBC 连接设置时区区域并避免找不到 SqlException 时区区域?

java - 为什么我看不到我的 Java/SalesForce/Google 应用程序?

java - 二进制 SVM 中的错误分类

mysql - 如何在列数据类型为 smallint 时查找年龄

java - MySQL使用Statement.RETURN_GENERATED_KEYS时出错

java - 未获取 Firebase 数据库生成的唯一 ID

mysql - 产品名称搜索查询