java Tomcat JDBC 异常池已耗尽

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13412824/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 12:37:42  来源:igfitidea点击:

Tomcat JDBC Exception PoolExhausted

javatomcatconnection-pooling

提问by user1597915

I am getting always the same exception , i have tried my best by doing searches to get the solution but without benefit.

我总是遇到同样的例外,我已经尽我最大的努力通过搜索来获得解决方案,但没有任何好处。

My exception is:

我的例外是:

SEVERE: Exception : org.apache.tomcat.jdbc.pool.PoolExhaustedException: [pool-2-thread-1] Timeout: Pool empty. Unable to fetch a connection in 30 seconds, none available[size:100; busy:100; idle:0; lastwait:30000].
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:672)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:187)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:128)
    at com.xxxxx.dbmanager.utils.DBManager.getConnection(DBManager.java:81)
    at com.xxxxx.dbmanager.utils.SQLManager.<init>(SQLManager.java:36)
    at ...
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

I have tried to increase the maximum number of connections in mysql DB.

我试图增加 mysql DB 中的最大连接数。

I am just wondering if a servlet running in the background and creating threads could be the problem? And how can i kill my threads when tasks are done ?

我只是想知道在后台运行并创建线程的 servlet 是否可能是问题所在?任务完成后如何终止线程?

Appreciating your help !!

感谢您的帮助!

回答by Nathan Hughes

From the error message it seems like your code is connecting to the database and never closing its connections.

从错误消息来看,您的代码似乎正在连接到数据库并且从未关闭其连接。

The way that the pool recovers connections is that application code has to call close on the connection when it's done with it, which returns the connection back to the pool. Otherwise as far as the pool knows all those connections are still busy.

池恢复连接的方式是应用程序代码必须在完成连接后调用 close ,这将连接返回到池中。否则,据池所知,所有这些连接仍然很忙。

My first guess at the cause is that your code is not even trying to close the connections. Some people, especially those coming from PHP (where it's common for this to get taken care of automatically), are surprised to find out that this is something that they have to do themselves.

我对原因的第一个猜测是您的代码甚至没有尝试关闭连接。有些人,尤其是那些来自 PHP(通常会自动处理此问题)的人,惊讶地发现这是他们必须自己做的事情。

Alternatively, some error condition could be causing an exception to be thrown where your code is not handling the exception correctly, and ends up skipping the call to close, this can happen when more than one jdbc resource gets closed in a single finally block. For more details see this answer.

或者,某些错误条件可能会导致在您的代码未正确处理异常的情况下引发异常,并最终跳过对 close 的调用,当多个 jdbc 资源在单个 finally 块中关闭时,就会发生这种情况。有关更多详细信息,请参阅此答案

Or maybe, your application is just busy and those threads are all trying to get work done. Check if the threads are doing anything: add logging to tell what they're doing, and check if there is network traffic between your application and the database.

或者,您的应用程序很忙,而这些线程都在努力完成工作。检查线程是否正在执行任何操作:添加日志记录以告知它们在做什么,并检查您的应用程序和数据库之间是否存在网络流量。

For how to kill threads see Servlet “has started a thread but failed to stop it” - memory leak in Tomcat. I don't think that's immediately relevant to the lost-connection issue, but it would be good to know. If you don't get this right it's possible to keep an old instance of the application alive in the background while your new instance is running.

有关如何杀死线程,请参阅Servlet“已启动线程但无法停止它”- Tomcat 中的内存泄漏。我认为这与失去连接的问题没有直接关系,但最好知道。如果您没有做到这一点,则可以在新实例运行时让应用程序的旧实例在后台保持活动状态。