我收到池错误超时等待空闲对象

时间:2013-12-05 13:26:48

标签: spring tomcat

  <Resource name="jdbc/name" auth="Container" type="javax.sql.DataSource"
               maxActive="100" maxIdle="30" maxWait="10000"
               username="root" password="root" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql:url?autoReconnect=true"/> 

我在Tomcat服务器上使用上面的语句创建了连接池。

一些Android应用程序使用Web服务连接我的应用程序。通过Web服务我发送和接收一些数据。 我收到了错误

SQLState: null
[2013-12-05 14:13:06,156]ERROR069688[http-8080-10] - org.hibernate.util.JDBCExceptionReporter.logExceptions(JDBCExceptionReporter.java:78) -
 Cannot get a connection, pool error Timeout waiting for idle object

我看到了Connection Pool Exception: Cannot get a connection, pool error Timeout waiting for idle object

但对我来说毫无头绪。

这是什么原因。

提前致谢...

1 个答案:

答案 0 :(得分:30)

此异常表明池管理器无法生成与等待请求者的可行连接,并且maxWait已经通过,因此会触发超时。有几个潜在的原因,但它们通常分为两大类:

  1. 数据库已关闭或无法访问。这可能是因为您忘记启动它,或者它崩溃了,或者您和DB之间的网络已经停止工作。但基本上,池已无法提供有效的新连接,因此请求者已等待新连接的时间超过超时并已放弃。这通常是不太可能的情况,因为在发生这种情况时您通常会看到其他错误。

  2. 连接池(设置为100最大活动状态)没有连接。这可能是由于需求量很大,或者它可能是连接泄漏的指示,其中连接永远不会返回到池中,并最终超过最大连接限制。这是更可能的原因...通常由于在完成数据库资源时没有关闭数据库资源而导致连接泄漏。

  3. 有时1和2创建此场景,如果说DB遇到错误,查询停止执行。当发生这种情况时,它就像连接泄漏一样,因为新连接会出现并阻止对DB的查询,并且永远不会被释放。最终所有连接都处于活动状态,并且请求连接的下一个线程将被放入等待队列,因为没有更多的连接要发出。由于数据库已经被软化,因此在第一个请求者在等待队列中超时之前,您将看不到任何其他异常。当Oracle DB后端崩溃时,我们常常使用Oracle UCP看到这种情况。

    我建议在发生这种情况时使用JConsole监视数据库池大小,并确定触发此错误的上述两种原因中的哪一种。然后,您可以尝试修复连接或操作池大小/超时参数以满足实际需求(您还可以在Tomcat中操作连接器参数以减少对应用程序的总体需求)。如果您在Tomcat中运行,通常只需运行JConsole(位于JDK bin目录中)并附加到tomcat进程,然后查看JMX控制台以查找池大小的位置...通常取决于数据源类型(dbcp vs oracle ucp vs etc)。然后,您可以双击字段值来绘制它们,以便随时跟踪它们。

    此外,您可能需要在Tomcat中启用JMX以使JConsole JMX监视工作。