当线程全部为空时,C3P0明显死锁?
我在 Tomcat 中使用 C3P0 作为连接池,并且看到非常令人担忧的错误:
2010-09-16 13:25:00,160 [Timer-0] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@43502400 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
2010-09-16 13:25:01,407 [Timer-0] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@43502400 -- APPARENT DEADLOCK!!! Complete Status:
Managed Threads: 10
Active Threads: 0
Active Tasks:
Pending Tasks:
com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@6e4151a7
Pool thread stack traces:
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#6,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#5,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#4,5,main]
java.lang.Object.wait(Native Method)
... many more, exact same stack trace
第 534 行是:
while (true) {
Runnable myTask;
synchronized ( ThreadPoolAsynchronousRunner.this ) {
while ( !should_stop && pendingTasks.size() == 0 )
ThreadPoolAsynchronousRunner.this.wait( POLL_FOR_STOP_INTERVAL ); // <- here
if (should_stop) ...
它看起来非常像所有线程都空闲。他们正在等待工作。 0 个活动线程,仅完成 1 个任务。关于出了什么问题有任何线索吗?
这是配置:
ds.setUser(userName);
ds.setPassword(password);
ds.setMaxPoolSize(16);
ds.setMaxConnectionAge(1800);
ds.setAcquireRetryAttempts(4);
ds.setMaxIdleTime(900);
ds.setNumHelperThreads(10);
ds.setCheckoutTimeout(1000);
I'm using C3P0 as a connection pool in Tomcat, and I'm seeing very worrying errors:
2010-09-16 13:25:00,160 [Timer-0] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@43502400 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
2010-09-16 13:25:01,407 [Timer-0] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@43502400 -- APPARENT DEADLOCK!!! Complete Status:
Managed Threads: 10
Active Threads: 0
Active Tasks:
Pending Tasks:
com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@6e4151a7
Pool thread stack traces:
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#6,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#5,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#4,5,main]
java.lang.Object.wait(Native Method)
... many more, exact same stack trace
Line 534 is:
while (true) {
Runnable myTask;
synchronized ( ThreadPoolAsynchronousRunner.this ) {
while ( !should_stop && pendingTasks.size() == 0 )
ThreadPoolAsynchronousRunner.this.wait( POLL_FOR_STOP_INTERVAL ); // <- here
if (should_stop) ...
It looks very much like all the threads are idle. They're waiting for work. 0 active threads, and only 1 task to complete. Any clues on what's going wrong?
Here's the configuration:
ds.setUser(userName);
ds.setPassword(password);
ds.setMaxPoolSize(16);
ds.setMaxConnectionAge(1800);
ds.setAcquireRetryAttempts(4);
ds.setMaxIdleTime(900);
ds.setNumHelperThreads(10);
ds.setCheckoutTimeout(1000);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
我刚刚在 Oracle 数据库中遇到了类似的问题,但在我的情况下,
托管线程
和活动线程
计数是相同的。对我来说,这实际上是一个身份验证错误,但由于我进行登录审核的方式而显示为明显死锁错误。
I just experienced a similar issue against an Oracle database, but in my case
Managed Thread
andActive Thread
counts were the same.For me it was actually an authentication error but appeared as the
APPARENT DEADLOCK
error because of the way I was doing login auditing.这听起来好像您已经从池中获取了连接,但没有及时返回。
当获取连接但在死锁检测超时内未将连接返回到池时,C3P0 确定“明显死锁”。
如果将连接获取移近“操作”并在数据库工作完成后立即将其返回到池中,则此消息将会消失。
This sounds like you have already acquired a connection from the pool and do not return it in time.
C3P0 determines "apparent deadlocks" when a connection is acquired but not returned to the pool within the deadlock detection timeout.
If you move the connection acquisition closer to the "action" and immediately return it to the pool after the database work is done, this message will disappear.
这将解决您的问题,
请查看:https:// forum.hibernate.org/viewtopic.php?t=947246&highlight=apparent+deadlock+c3p0
记住在完成语句后关闭它们!
This will sort out your problem
check out : https://forum.hibernate.org/viewtopic.php?t=947246&highlight=apparent+deadlock+c3p0
Remember to close your statements after you are done with them !!
我对答案的评论 https://stackoverflow.com/a/18192588/1019307 收到了足够多的赞成票,表明它应该成为一个答案。
我收到此错误是因为我无法通过防火墙到达数据库服务器。请检查这是否是您的问题。
My comment on answer https://stackoverflow.com/a/18192588/1019307 received enough up-votes to suggest it should be an answer.
I received this error because I couldn't get through the firewall to the database server. Check to see if that is your problem.
@eebbesen,我遇到了和你一样的错误。我正在运行 Tomcat 版本 9.0.6。我的 Maven 项目中有 hibernate core 版本 5.2.10、hibernate c3p0 版本 3.6.3。我的不是身份验证错误,而是由于我之前更改了计算机名称。这对 tomcat 没有立即影响,但是在重新启动我的机器后,当我尝试通过 eclipse (Oxygen 2) 再次启动 tomcat 时,由于您提出的问题,我无法再启动 eclipse。
我用谷歌搜索了这个,找到了这个链接,这让我注意到了这个问题:
https://community.oracle .com/thread/339825
其中写着:
后来它提到在哪里可以找到这个 tnsnames.ora 文件,对我来说它在这里:
看着这个 tnsnames.ora 文件,我看到了这个:
但我最近将我的机器重命名为 MyMachineName-5。我将 7 更改为 5 并保存了文件。我检查了该目录中的“listener.ora”文件,它也有同样的问题:
我将 7 更改为 5 并保存该文件。
然后我打开任务管理器,单击“服务”选项卡,查看“Oracle”服务。我重新启动了:OracleXETNSListener、OracleXEClrAgent、OracleServiceXE。我又去eclipse中重启tomcat,这次又出现问题了。
附录:
我还用谷歌搜索了这个:
https://community.oracle.com/thread/2267906
这导致我尝试:
1)关闭Windows Defender中的防火墙(已经关闭mcaffee防火墙)
2)启动sqlplus以确保我可以使用我在休眠文件中使用的凭据登录:hibernate.cfg.xml
C:\oraclexe\app\oracle\product\11.2.0\server\bin\sqlplus.exe
3) 启动 Oracle Database 11g 的桌面快捷方式
即使在我修复了计算机名称问题之后,这对我来说仍然失败,但我仍然有去调查。
4) 使用 dbVisualizer,我尝试连接到 Oracle。这仅在我解决了 .ora 文件机器名问题后才起作用:双击连接并单击“ping 服务器”按钮。
@eebbesen, I got the same error as you did. I am running Tomcat version 9.0.6. I have hibernate core ver 5.2.10, hibernate c3p0 ver 3.6.3 in my maven project. Mine was not an authentication error, but rather due to me having previously changed the name of my computer. This did not have an immediate effect on tomcat, but upon a restart of my machine, when I tried to bring up tomcat again via eclipse (Oxygen 2), I could no longer start eclipse due exactly to the issue you raised.
I googled this and I found this link, which tipped me off to the issue:
https://community.oracle.com/thread/339825
where it says:
Later it mentions where to find this tnsnames.ora file, and for me it was here:
Looking at this tnsnames.ora file, I saw this:
But I had recently renamed my machine to MyMachineName-5. I changed the 7 to a 5 and saved the file. I checked the "listener.ora" file in this directory, and it had the same issue:
I changed the 7 to a 5 and saved the file.
Then I opened Task Manager, clicked the "Services" tab, and looked at the "Oracle" services. I did a restart on: OracleXETNSListener, OracleXEClrAgent, OracleServiceXE. I went to restart tomcat in eclipse again, and this time there was now problem.
Appendix:
I also googled this:
https://community.oracle.com/thread/2267906
This lead me to try:
1) Turned off the firewall in Windows Defender (already turned off mcaffee firewall)
2) Started sqlplus to make sure that I could log in with the credentials I was using in my hibernate file: hibernate.cfg.xml
C:\oraclexe\app\oracle\product\11.2.0\server\bin\sqlplus.exe
3) Started the desktop shortcut to Oracle Database 11g
This failed for me even after I fixed the machine name issue though, something I still have to look into.
4) Using dbVisualizer, I tried making a connection to Oracle. This only worked after I resolved the .ora file machine name issue: double click the connection and click the "ping server" button.
我遇到了同样的问题,但原因有点难以发现,因为它是由一些同时资源试图同时获取连接引起的。
正如您所看到的,如果池尚未初始化,则提供通过调用设置函数来初始化它的代码。
问题在于,许多资源在程序开始时尝试获取连接,因此超过一个实例化池会在一段时间后导致您的问题。
解决方案只是声明该方法是同步的,以在调用该方法并且它仍在实例化池中时阻止其他资源。
这可能是不使用单例的设计错误,但修复了缺乏某些性能的问题。
I've had the same problem but the cause was a bit hard to spot as it was caused by some simultaneous resources trying to acquire a connection at the same time.
As you can read if the pool had not been initialized the code provided to init it by calling a setup function.
The problem was that many resources were trying to acquire the connection at the beginning of the program so more than one were instantiating the pool causing your problem after a while.
The solution was just to declare the method synchronized to keep out other resources while one has called the method and it's still inside instantiating the pool for instance.
This may be a design error for not using a singleton but fixes the problem lacking some performance.
我们遇到了这个问题,并通过将其添加到 C3P0 配置来解决它:
按照: 来自C3P0文档
We ran into this problem and solved it by adding this to the C3P0 config:
as per: this from the C3P0 doc
我通过正确关闭 Statement 和 Resultset 实例(不知何故未关闭)解决了相同的(无法检测)问题:
I had the same (was unable to detect) problem solved by correctly closing Statement and Resultset instances (somehow left unclosed):
你好,我的朋友只是发表评论,我也有同样的情况。我刚刚配置了我的 spring-hibernate eclipse 项目并显示了相同的异常,应该注意的是我的项目仍然没有任何查询。
我通过以下步骤解决了该问题:
1)清理项目:项目-->干净的...
2)构建项目:项目-->构建项目
我希望它对你有用。
Hi my friend just to comment, I had the same case. I just configured my spring-hibernate eclipse project and showed up the same exception, it should be noted that my project still does not have any query.
I resolved that issue with below steps:
1) Clean project : Project--> Clean...
2) Build project : Project--> Build Project
I hope it works for you.
我突然遇到了同样的问题:在注意到仅在调试模式下启动应用程序(我使用 IntelliJ)时才出现死锁并且在正常运行时没有问题后,我开始挖掘它。
我终于发现断点阻塞了连接:我不知道为什么 Intellij 没有“监听”应用程序正在通过该断点,而是由于断点而在某处挂起,这导致 明显的死锁
删除项目中的所有断点后,一切又开始顺利了。
希望这对某人有帮助
I've just had the same problem suddenly: after noticing that the deadlock was present only when launching my application in debug mode (I'm using IntelliJ) and it was fine when running with normal run, I started to dig it.
I finally figured out that a breakpoint was blocking the connection: I don't know why Intellij didn't "listen" that the application was passing through that breakpoint, but was hanged somewhere cause of a breakpoint, and this was causing appartent deadlock
After removing all breakpoints in my project, everything started smooth again.
Hope this helps someone
在部署应用程序时,在 glassfish4 服务器上也遇到了类似的问题。原来是数据库配置问题。只需确保您的数据库连接配置正确,验证配置中提供的主机名是否允许连接到数据库。尝试使用配置的用户名和主机名/域手动连接到数据库。如果需要,允许 db 用户从所需的域进行连接。使用正确的数据库配置重建应用程序,然后部署它。
Similar problem was encountered on glassfish4 server while deploying the application. Turned out it was a database configuration issue. Just make sure your database connectivity configurations are proper, verify that the hostname provided in the configuration allows the connection to database. Try connecting to the database manually with the configured username and the hostname/domain. If required, allow the db user to connect from the required domain. Rebuild the application with correct db configurations and then deploy it.